how to join an django model object response - python

I have this Django/Python call:
Stuff = Source.object.value_list(dbtype, host)
What I want to do is create this string:
`"mssql#12.12.12.12, MySQL#23.23.23.23"`
I tried to peform a join: ",".join(Stuff.dbtype + " " + Stuff.host) and that failed miserably.
Is there a version of the join call that will do what I'm looking for without manually iterating through my object?
Thanks.

You should use values instead of values_list:
stuff = Source.objects.values('dbtype', 'host')
Then:
stuffs = [i['dbtype'] + '#' + i['host'] for i in stuff]
result = ', '.join(stuffs)
or:
def compose(stuff):
return stuff['dbtype'] + '#' + stuff['host']
temp = map(compose, stuffs)
result = reduce(lambda x, y: x + ', ' + y, temp)

Firstly, values_list return list of tuples, so you can't write Stuff.dbtype.
Secondly, str.join takes iterable object as parameter like list.
So you can rewrite your code like this:
Stuff = Source.object.values_list(dbtype, host)
result = ', '.join([dbtype + '#' + host for dbtype, host in Stuff])

Related

how to force the code to parse specific POST call response

I'm making three post calls one by one and getting tree response. My code is always taking last response and passing it on. The question is how to force the code to parse second or first response not last one.
This is my method with for loop and range3.
def create_card_on_the_board_call(self, id_list, card_count, card_name):
global create_card
for i in range(card_count):
create_card = self.rest_api_helper.post_call(
self.base_url + '/cards?' + 'key=' + test_config[
'key'] + '&' + 'token=' + test_config[
'token'] + '&' + f'idList={id_list}' + '&' + f'name={card_name}', headers=None)
return create_card.json()
response looks like that received response {"id":"5f9dcffaa96f144d311deaa5","checkItemStates":[]}
I need id from first or second response not third. Also I need all three calls.
and this is how I'm calling the post
card_count = 3
card_name = 'someCard'
create_card_on_the_board = api_board.create_card_on_the_board_call(id_list=create_list_on_the_board["id"],
card_count=card_count, card_name=card_name)
now my method is looking like this:
def create_card_on_the_board_call(self, id_list, card_count, card_name):
global create_card
responses = []
for i in range(card_count):
create_card = self.rest_api_helper.post_call(
self.base_url + '/cards?' + 'key=' + test_config[
'key'] + '&' + 'token=' + test_config[
'token'] + '&' + f'idList={id_list}' + '&' + f'name={card_name}', headers=None)
responses.append(create_card)
return responses[2].json()
and I could select which card I want to pass but still dont know how to use as a proper argument in next call? e.g.
new_card_name = 'NewCardName2'
update_card = api_board.update_card_call(card_id=create_card_on_the_board['id'], new_card_name=new_card_name)
def update_card_call(self, card_id, new_card_name):
update_card = self.rest_api_helper.put_call(
self.base_url + '/cards/' + f'{card_id}' + '?' + 'key=' + test_config[
'key'] + '&' + 'token=' + test_config[
'token'] + '&' + f'name={new_card_name}', headers=None)
return update_card.json()
so here I want to use different create_card_on_the_board but I dont know how? Still taking the same card as in return responses[2].json(). I tried card_id=create_card_on_the_board[1]['id']
but its not working as this is not a list
You could put all of the responses in a list so you could get them all and then decide what to do with them. Here's how you'd do that:
def create_card_on_the_board_call(self, id_list, card_count, card_name):
responses = []
for i in range(card_count):
create_card = self.rest_api_helper.post_call(
self.base_url + '/cards?' + 'key=' + test_config[
'key'] + '&' + 'token=' + test_config[
'token'] + '&' + f'idList={id_list}' + '&' + f'name={card_name}', headers=None)
responses.append(create_card)
// Logic here determines which response to return and sets `x = 0, 1 or 2`
return responses[x].json()
So now you have a list named responses after your loop completes, and you can do whatever you want with it. I put a comment to show kinda what you seem to be talking about in your question. You could just return the whole list with return responses and let the caller worry about which one to do what with.

concatinating multiple strings from dictionary and save in file using python

I able to write hostname in the /tmp/filter.log but any hint how can i write all three values[hostname, owner, seats] in the file?
def list_hosts(nc):
resp = nc.send_service_request('ListHosts', json.dumps({}))
result = resp['result']
l = []
f=open("/tmp/filter.log", "w+")
for r in result:
if "team-prod" in r['owner']:
print r['owner'], r['hostname'], r['seats']
f.write(r['hostname'] + "\n")
f.close()
l.append(r['hostname'])
return l
nc = create_client('zone', 'team_PROD_USERNAME', 'team_PROD_PASSWORD')
l = list_hosts(nc)
print l
The file should have entries as below:
team-prod\*, np-team-052, [u'123123123-18d1-483d-9af8-169ac66b26e4']
Current entry is:
np-team-052
f.write(str(r['owner']) + ', ' + str(r['hostname']) + ', ' + str(r['seats']) + '\n')

String Indices must be integers, not str - API

I have an interesting behavior happening with my program.
i have the following methods:
def getMarket(self, Currency):
return self.public_api('GetMarket/' + Currency + '_BTC')
def getBalance(self, Currency):
self.api_params.clear()
self.api_params['Currency'] = Currency
return self.private_api('GetBalance')
my_api = buyBot(API_KEY, API_SECRET)
pumpCoin = my_api.getMarket('OSC')
pumpRawRate = pumpCoin['Data']['High']
pumpRawQty = .02
pumpBuyRate = my_api.calculateBuy(pumpRawRate)
pumpQty = float(pumpRawQty)/float(pumpBuyRate)
pumpSellRate = pumpCoin['Data']['Low']
pumpSellCoin = my_api.getBalance('OSC')
pumpSellAmount = pumpSellCoin["Data"]["Total"]
print str(pumpRawRate) + '\n' + str(pumpBuyRate) + '\n' + str(pumpSellRate) + '\n' + str(pumpQty) + '\n' + str(pumpSellAmount)`
From section: pumpCoin = my_api.getMarket('OSC') to pumpSellRate = pumpCoin['Data']['Low'], i have no problems getting the information and working with it.
Problem seems to be starting with line: pumpSellCoin = my_api.getBalance('OSC')
I get the following Error message:
Traceback (most recent call last):
File "C:\XXXXXX.py", line 92, in <module>
pumpSellAmount = pumpSellCoin["Data"]["Total"]
TypeError: string indices must be integers, not str
if i run: print (my_api.getBalance('OSC'), i am able to see all the private API information that is retrieved by that call, however i am not sure why it is giving me a problem when i try to call 1 specific item in the stack.
Let me know if you need any more information on this.
Any help will be greatly appreciated.
I have looked at the other posts and so far i can't seem to figure out the exact cause.
This is the private_api code
def private_api(self, meth):
time.sleep(1)
params = self.api_params
url = self.apisite + meth
nonce = str(int(time.time()))
post_data = json.dumps(params)
hash = hashlib.md5()
hash.update(post_data)
base64hash = base64.b64encode(hash.digest())
sig = self.apikey + "POST" + urllib.quote_plus(url).lower() + nonce + base64hash
hmacsig = base64.b64encode(hmac.new(base64.b64decode(self.apisecret), sig, hashlib.sha256).digest())
hdr = "amx " + self.apikey + ":" + hmacsig + ":" + nonce
headers = { 'Authorization': hdr, 'Content-Type':'application/json; charset=utf-8' }
request = urllib2.Request(url, data=post_data, headers=headers)
return urllib2.urlopen(request).read()
Please add this to your code:
print('pumpSellCoin', type(pumpSellCoin["Data"]), type(pumpSellCoin["Data"]["Total"]))
pumpSellAmount = pumpSellCoin["Data"]["Total"]
This will show you that one of your variables is a list or a string and not a dictionary and you need to access is using a number and not a name like "Data" or "Total"
Try this example:
test = 'abcde'
print(type(test))
print(test[0])
print(test[2:4])
print(test['whatever']) # this results in TypeError: string indices must be integers
if i run the program as follows:
my_api = buyBot(API_KEY, API_SECRET)
pumpCoin = my_api.getMarket('OSC')
pumpRawRate = pumpCoin['Data']['High']
pumpRawQty = .02
pumpBuyRate = my_api.calculateBuy(pumpRawRate)
pumpQty = float(pumpRawQty)/float(pumpBuyRate)
pumpSellRate = pumpCoin['Data']['Low']
pumpSellBal = my_api.getBalance('OSC')
print pumpSellBal
#print('pumpSellBal', type(pumpSellBal["Data"]), type(pumpSellBal["Data"]["Total"]))
#pumpSellAmount = pumpSellBal['Data']['Total']
print str(pumpRawRate) + '\n' + str(pumpBuyRate) + '\n' + str(pumpSellRate) + '\n' + str(pumpQty) #+ '\n' + str(pumpSellAmount)
i get the following results:
{"Success":true,"Error":null,"Data":[{"CurrencyId":235,"Symbol":"OSC","Total":8561.03652012,"Available":0.00000000,"Unconfirmed":0.00000000,"HeldForTrades":8561.03652012,"PendingWithdraw":0.00000000,"Address":null,"Status":"OK","StatusMessage":null,"BaseAddress":null}]}
1.61e-06
2.415e-06
1.25e-06
8281.57349896
So i am definitely able to communicate back and forward, however the issue only seems to be when i try to work with a single piece of information from pumpSellBal = my_api.getBalance('OSC')

Delete Specific Part Of A String

I want to delete the part after the last '/' of a string in this following way:
str = "live/1374385.jpg"
formated_str = "live/"
or
str = "live/examples/myfiles.png"
formated_str = "live/examples/"
I have tried this so far ( working )
import re
for i in re.findall('(.*?)/',str):
j += i
j += '/'
Output :
live/ or live/examples/
I am a beginner to python so just curious is there any other way to do that .
Use rsplit:
str = "live/1374385.jpg"
print (str.rsplit('/', 1)[0] + '/')
live/
str = "live/examples/myfiles.png"
print (str.rsplit('/', 1)[0] + '/')
live/examples/
You can also use .rindex string method:
s = 'live/examples/myfiles.png'
s[:s.rindex('/')+1]
#!/usr/bin/python
def removePart(_str1):
return "/".join(_str1.split("/")[:-1])+"/"
def main():
print removePart("live/1374385.jpg")
print removePart("live/examples/myfiles.png")
main()

remove similar lines in text file

I am not using Python but I have script in python:
part of script
elif line.find("CONECT") > -1:
con = line.split()
line_value = line_value + 1
#print line_value
#print con[2]
try:
line_j = "e" + ', ' + str(line_value) + ', ' + con[2] + "\n"
output_file.write(line_j)
print(line_j)
line_i = "e" + ', ' + str(line_value) + ', ' + con[3] + "\n"
output_file.write(line_i)
print(line_i)
line_k = "e"+ ', ' + str(line_value) + ', ' + con[4] + "\n"
print(line_k)
output_file.write(line_k)
except IndexError:
continue
which give .txt output in format
e, 1, 2
e, 1, 3
e, 1, 4
e, 2, 1
e, 2, 3
etc.
I need remove similar lines with the same numbers, but no matter on order this numbers
i.e. line e, 2, 1..
Is it possible?
Of course, it is better to modify your code to remove that lines BEFORE you're writing them to file. You can use a list to store already saved values, and on each itereation, perfom a search if the values you're want to add is already exists in that list. The code below isn't tested and optimized, but it explains an idea:
# 'added = []' should be placed somewhere before 'if'
added = []
# you part of code
elif line.find("CONECT") > -1:
con = line.split()
line_value = line_value + 1
try:
line_j = "e, %s, %s\n" % (str(line_value),con[2])
tmp = sorted((str(line_value),con[2]))
if tmp not in added:
added.append(tmp)
output_file.write(line_j)
print(line_j)
line_i = "e, %s, %s\n" % (str(line_value),con[3])
tmp = sorted((str(line_value),con[3]))
if tmp not in added:
added.append(tmp)
output_file.write(line_i)
print(line_i)
line_k = "e, %s, %s\n" % (str(line_value),con[4])
tmp = sorted((str(line_value),con[4]))
if tmp not in added:
added.append(tmp)
print(line_k)
output_file.write(line_k)
except IndexError:
continue
Here is a comparison method for two lines of your file:
def compare(line1, line2):
els1 = line1.strip().split(', ')
els2 = line2.strip().split(', ')
return Counter(els1) == Counter(els2)
See the documentation for the Counter class.
If the count of elements doesn't matter you can replace the Counter class with set instead
The following approach should work. First add the following line further up in your code:
seen = set()
Then replace everything inside the try with the following code:
for con_value in con[2:5]:
entry = frozenset((line_value, con_value))
if entry not in seen:
seen.append(entry)
line_j = "e" + ', ' + str(line_value) + ', ' + con_value + "\n"
output_file.write(line_j)
print(line_j)
Make sure this code is indented to the same level as the code it replaces.

Categories