Create dictionary from unwieldly string of keyvalues - python-3.x

I need to transform a list of strings similar to this:
"ABOC000 RECORD 0 Msg-type\=0220 Bit-map\=3450G83H403894JH Xbit-map\=0000000000000010 Proc code\=312000 Tran amt\=000000000000 Tran datetime\=0613064645 Trace nbr\=000000 Local time\=02:46:37 Local date\=06/13 Exp date\=24/02 Sett date\=06/13 Merchant\=6011 Pos entry\=051 Card seq no\=000 Acqr inst id\=2349823498 Cord \=23049583049583405983045983405983405900 Retr ref\=111111111111 Resp code\=00 Crd acpt trmid\=CS61252 Crd acpt id\=ISPA/PULSE Crd acpt loc\=000 8TH AVENUE BOREALIS XXUS Name\=MERCHANT NAME Tran curr\=840 Natl cond code\=1010000002U Reason codes\=004 Rsn code map\=40 Advice reason\=31 Ddsi data len\=022 Ddsi data map\=B2 Pseudo term\=070792 Acqr netid\=PUL Processor id\=INT789 Proc flags\= Info text\=NI24PS20ID16 03 "
into a list of dicts with key/values.
This is using python 3.7 -- I've gone down the list comprehension and regex paths, but have not found a workable solution yet. The difficult lies around:
keys and values sometimes being multiple words (having spaces)
some keys not always being present
A short example of what I'm aiming to end up with:
[{"RECORD":"0", "Msg-type":"0220", "Bit-map":"3450G83H403894JH", "Xbit-map":"0000000000000010", "Proc code":"312000" ... }]

Assuming that the values don't contain any whitespace (otherwise it would be hard to distinguish what part belongs to the previous value or to the next key), and stripping off the beginning of the string (not sure how the {'RECORD': '0'} fits in the picture), you can use re.findall with the following regex:
s = r"Msg-type\=0220 Bit-map\=3450G83H403894JH Xbit-map\=0000000000000010 Proc code\=312000 Tran amt\=000000000000 Tran datetime\=0613064645 Trace nbr\=000000 Local time\=02:46:37 Local date\=06/13 Exp date\=24/02 Sett date\=06/13 Merchant\=6011 Pos entry\=051 Card seq no\=000 Acqr inst id\=2349823498 Cord \=23049583049583405983045983405983405900 Retr ref\=111111111111 Resp code\=00 Crd acpt trmid\=CS61252 Crd acpt id\=ISPA/PULSE Crd acpt loc\=000 8TH AVENUE BOREALIS XXUS Name\=MERCHANT NAME Tran curr\=840 Natl cond code\=1010000002U Reason codes\=004 Rsn code map\=40 Advice reason\=31 Ddsi data len\=022 Ddsi data map\=B2 Pseudo term\=070792 Acqr netid\=PUL Processor id\=INT789 Proc flags\= Info text\=NI24PS20ID16 03 "
d = dict(re.findall(r'([A-Za-z][A-Za-z \-]*)\\=([^\s]+)', s))
Which gives:
{'Acqr inst id': '2349823498',
'Acqr netid': 'PUL',
'Advice reason': '31',
'Bit-map': '3450G83H403894JH',
'Card seq no': '000',
'Cord ': '23049583049583405983045983405983405900',
'Crd acpt id': 'ISPA/PULSE',
'Crd acpt loc': '000',
'Crd acpt trmid': 'CS61252',
'Ddsi data len': '022',
'Ddsi data map': 'B2',
'Exp date': '24/02',
'Info text': 'NI24PS20ID16',
'Local date': '06/13',
'Local time': '02:46:37',
'Merchant': '6011',
'Msg-type': '0220',
'NAME Tran curr': '840',
'Natl cond code': '1010000002U',
'Pos entry': '051',
'Proc code': '312000',
'Processor id': 'INT789',
'Pseudo term': '070792',
'Reason codes': '004',
'Resp code': '00',
'Retr ref': '111111111111',
'Rsn code map': '40',
'Sett date': '06/13',
'TH AVENUE BOREALIS XXUS Name': 'MERCHANT',
'Trace nbr': '000000',
'Tran amt': '000000000000',
'Tran datetime': '0613064645',
'Xbit-map': '0000000000000010'}

Related

How to apply recursion over this problem and solve this problem

The Problem is:-
Given a digit string, return all possible letter combinations of each digits according to the buttons on a telephone, that the number could represent.
The returned strings must be lexicographically sorted.
Example-1 :-
Input : “23”
Output : ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
Example-2 :-
Input : “9”
Output: [“w”, “x”, “y”, “z”]
Example-3 :-
Input : “246”
Output : ["agm", "agn", "ago", "ahm", ..., "cho", "cim", "cin" "cio"] {27 elements}
I've squeezed my brain on this, and I've tried a lot but I'm not getting ahead of this part, what I've tried is to use a recursive function that zips the individual letters of each digit with each other letters and use itertools.combinations() over it, but I'm unable to complete this function and I'm unable to get ahead of this.
What I've tried is :-
times, str_res = 0, ""
def getval(lst, times):
if times==len(lst)-1:
for i in lst[times]:
yield i
else:
for i in lst[times]:
yield i + getval(lst, times+1)
dct = {"2":("a","b","c"), "3":("d","e","f"), "4":("g","h","i"),
"5":("j","k","l"), "6":("m","n","o"), "7":("p","q","r","s"),
"8":("t","u","v"), "9":("w","x","y","z"), "1":("")}
str1, res = "23", []
if len(str1)==1:
print(dct[str1[0]])
else:
temp = [dct[i] for i in str1]
str_res = getval(temp, times)
print(str_res)
Please suggest me your ideas over this problem or in completing the function...
It's not itertools.combinations that you need, it's itertools.product.
from itertools import product
def all_letter_comb(s, dct):
for p in product(*map(dct.get, s)):
yield ''.join(p)
dct = {"2":("a","b","c"), "3":("d","e","f"), "4":("g","h","i"),
"5":("j","k","l"), "6":("m","n","o"), "7":("p","q","r","s"),
"8":("t","u","v"), "9":("w","x","y","z"), "1":("")}
for s in ['23', '9', '246']:
print(s)
print(list(all_letter_comb(s, dct)))
print()
Output:
23
['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']
9
['w', 'x', 'y', 'z']
246
['agm', 'agn', 'ago', 'ahm', 'ahn', 'aho', 'aim', 'ain', 'aio', 'bgm', 'bgn', 'bgo', 'bhm', 'bhn', 'bho', 'bim', 'bin', 'bio', 'cgm', 'cgn', 'cgo', 'chm', 'chn', 'cho', 'cim', 'cin', 'cio']
If I am not wrong this is leet code problem. You can find multiple answers there.

Error creating invoice from custom module (Odoo 13)

I am trying to create an invoice from a custom object but I am getting errors from on validation .When I post, i get the following error: "
ValueError: Wrong value for account.move.line_ids: {'display_type': 'line_section', 'name': 'Phone Bill', 'product_id': 11783, 'product_uom_id': 19, 'current_reading': 66.0, 'current_date': datetime.date(2020, 11, 3), 'quantity': 17.0, 'price_unit': 565.0, 'account_id': 19, 'debit': 9605.0, 'credit': 0.0}
current_date and current_reading are custom fields i created. I am aware that Odoo automatically creates values for line_ids from invoice_line_ids if line_ids is not provided, so I am really stuck about this error.
Here's my code for creating the invoice:
class ReadingCorrection(models.TransientModel):
_name = 'reading.upload.wizard'
_description = 'Validate reading uploads'
def validate_entry(self):
active_ids = self._context.get('active_ids', []) or []
company = self.env.user.company_id
journal = self.env['account.move'].with_context(force_company=company.id, type='out_invoice')._get_default_journal()
for reads in self.env['reading.upload'].browse(active_ids):
if reads.reading >= reads.previous_reading: # and reads.state == 'draft':
account = reads.product_id.product_tmpl_id._get_product_accounts()['income']
if not account:
raise UserError(_('No account defined for product "%s".') % reads.product_id.name)
invoice = {
'type': 'out_invoice',
'invoice_date':reads.read_date,
'narration': reads.remark,
'invoice_user_id': reads.current_user.id,
'partner_id': reads.meter_id.customer_id.id,
'journal_id': 1,#journal.id,
'currency_id': reads.meter_id.customer_id.currency_id.id,
'doc_type': 'bill',
'invoice_line_ids':[(0,0, {
'name': reads.product_id.name,
'product_id': reads.product_id.id,
'product_uom_id': reads.product_id.uom_id.id,
'current_reading': reads.reading,
'previous_reading': reads.previous_reading,
'current_date': reads.read_date,
'quantity': reads.reading - reads.previous_reading,
'price_unit': reads.product_id.product_tmpl_id.lst_price,
'account_id': account.id,
})]
}
moves = self.env['account.move'].with_context(default_type='out_invoice').create(invoice)
#invoice = self.env['account.move'].sudo().create(invoice)
reads.write({'state':'uploaded'})
Any help given will be appreciated. Thanks
If you want to create invoices, in the lines you should not use the debit and credit fields since these are calculated, as it is a product line, you should not use display_type, since the line_section type is treated as an annotation and not as a price calculation line.
In the invoice data, when linking the lines 'invoice_line_ids': inv_line_ids an instruction must be specified to process the lines in your case it would be as follows 'invoice_line_ids': (0, 0, inv_line_ids) for greater information visit this page.

How to parse complicated CSV file

I received a CSV file that includes a combination of string and tuple elements and cannot find a way to parse it properly. Am I missing something obvious?
csvfile
"presentation_id","presentation_name","sectionId","sectionNumber","courseId","courseIdentifier","courseName","activity_id","activity_prompt","activity_content","solution","event_timestamp","answer_id","answer","isCorrect","userid","firstname","lastname","email","role"
"26cc7957-5a6b-4bde-a996-dd823f54ece7","3-Axial Skeleton F18","937c47b0-cc66-4938-81de-1b1b58388499","001","3b5b5e49-1798-4eab-86d7-186cf59149b4","MOVESCI 230","Human Musculoskeletal Anatomy","62d059e8-9ab4-41d4-9eb8-00ba67d9fac9","A blow to which side of the knee might tear the medial collateral ligament?","{"choices":["medial","lateral"],"type":"MultipleChoice"}","{"solution":[1],"selectAll":false,"type":"MultipleChoice"}","2018-09-30 23:54:16.000","7b5048e5-7460-49f8-a64a-763b7f62d771","{"solution":[1],"type":"MultipleChoice"}","1","57ba970d-d02b-4a10-a64d-56f02336ee08","Student","One","student1#example.com","Student"
"26cc7957-5a6b-4bde-a996-dd823f54ece7","3-Axial Skeleton F18","937c47b0-cc66-4938-81de-1b1b58388499","001","3b5b5e49-1798-4eab-86d7-186cf59149b4","MOVESCI 230","Human Musculoskeletal Anatomy","f82cb32b-45ce-4d3a-aa74-b3fa1a1038a2","What is the name of this movement?","{"choices":["right rotation","left rotation","right lateral rotation","left lateral rotation"],"type":"MultipleChoice"}","{"solution":[1],"selectAll":false,"type":"MultipleChoice"}","2018-09-30 23:20:33.000","d6cce4d9-37ae-409e-afc5-54ad79f86226","{"solution":[3],"type":"MultipleChoice"}","0","921d1b9b-f550-4289-89f1-2a805b27eeb3","Student","Two","student2#example.com","Student"
where 1st row is titles, 2nd starts the data
with open(filepathcsv) as csvfile:
readCSV = csv.reader(csvfile)
for row in readCSV:
numcolumns = len(row)
print(numcolumns,": ",row)
yields:
20 : ['presentation_id', 'presentation_name', 'sectionId', 'sectionNumber', 'courseId', 'courseIdentifier', 'courseName', 'activity_id', 'activity_prompt', 'activity_content', 'solution', 'event_timestamp', 'answer_id', 'answer', 'isCorrect', 'userid', 'firstname', 'lastname', 'email', 'role']
25 : ['26cc7957-5a6b-4bde-a996-dd823f54ece7', '3-Axial Skeleton F18', '937c47b0-cc66-4938-81de-1b1b58388499', '001', '3b5b5e49-1798-4eab-86d7-186cf59149b4', 'MOVESCI 230', 'Human Musculoskeletal Anatomy', '62d059e8-9ab4-41d4-9eb8-00ba67d9fac9', 'A blow to which side of the knee might tear the medial collateral ligament?', '{choices":["medial"', 'lateral]', 'type:"MultipleChoice"}"', '{solution":[1]', 'selectAll:false', 'type:"MultipleChoice"}"', '2018-09-30 23:54:16.000', '7b5048e5-7460-49f8-a64a-763b7f62d771', '{solution":[1]', 'type:"MultipleChoice"}"', '1', '57ba970d-d02b-4a10-a64d-56f02336ee08', 'William', 'Muter', 'wmuter#umich.edu', 'Student']
27 : ['26cc7957-5a6b-4bde-a996-dd823f54ece7', '3-Axial Skeleton F18', '937c47b0-cc66-4938-81de-1b1b58388499', '001', '3b5b5e49-1798-4eab-86d7-186cf59149b4', 'MOVESCI 230', 'Human Musculoskeletal Anatomy', 'f82cb32b-45ce-4d3a-aa74-b3fa1a1038a2', 'What is the name of this movement?', '{choices":["right rotation"', 'left rotation', 'right lateral rotation', 'left lateral rotation]', 'type:"MultipleChoice"}"', '{solution":[1]', 'selectAll:false', 'type:"MultipleChoice"}"', '2018-09-30 23:20:33.000', 'd6cce4d9-37ae-409e-afc5-54ad79f86226', '{solution":[3]', 'type:"MultipleChoice"}"', '0', '921d1b9b-f550-4289-89f1-2a805b27eeb3', 'Noah', 'Willett', 'willettn#umich.edu', 'Student']
csv.reader is parsing each row differently because of complicated structure with embedded curly braced elements.
...but I expect 20 elements in each row.
The in the records, not the code. Your code works fine. To solve the problem you need to fix csv file because the fields with json content weren't serialised correctly.
Just change one quote sign " to two signs "" to escape them.
Here the example of fixed csv row.
"26cc7957-5a6b-4bde-a996-dd823f54ece7","3-Axial Skeleton F18","937c47b0-cc66-4938-81de-1b1b58388499","001","3b5b5e49-1798-4eab-86d7-186cf59149b4","MOVESCI 230","Human Musculoskeletal Anatomy","f82cb32b-45ce-4d3a-aa74-b3fa1a1038a2","What is the name of this movement?","{""choices"":[""right rotation"",""left rotation"",""right lateral rotation"",""left lateral rotation""],""type"":""MultipleChoice""}","{""solution"":[1],""selectAll"":false,""type"":""MultipleChoice""}","2018-09-30 23:20:33.000","d6cce4d9-37ae-409e-afc5-54ad79f86226","{""solution"":[3],""type"":""MultipleChoice""}","0","921d1b9b-f550-4289-89f1-2a805b27eeb3","Student","Two","student2#example.com","Student"
And the result of your code after fix:
20 : ['26cc7957-5a6b-4bde-a996-dd823f54ece7', '3-Axial Skeleton F18', '937c47b0-cc66-4938-81de-1b1b58388499', '001', '3b5b5e49-1798-4eab-86d7-186cf59149b4', 'MOVESCI 230', 'Human Musculoskeletal Anatomy', 'f82cb32b-45ce-4d3a-aa74-b3fa1a1038a2', 'What is the name of this movement?', '{"choices":["right rotation","left rotation","right lateral rotation","left lateral rotation"],"type":"MultipleChoice"}', '{"solution":[1],"selectAll":false,"type":"MultipleChoice"}', '2018-09-30 23:20:33.000', 'd6cce4d9-37ae-409e-afc5-54ad79f86226', '{"solution":[3],"type":"MultipleChoice"}', '0', '921d1b9b-f550-4289-89f1-2a805b27eeb3', 'Student', 'Two', 'student2#example.com', 'Student']
Thank you all for your suggestions!
Also, my apologies, as I did not include the raw CSV file I was trying to parse (example here:)
"b5ae18d3-b6dd-4d0a-84fe-7c43df472571"|"Climate_Rapid_Change_W18.pdf"|"18563b1e-a467-44b3-aed7-3607a1acd712"|"001"|"c86c8c8d-dca6-41cd-a010-a83e40d93e75"|"CLIMATE 102"|"Extreme Weather"|"278c4561-c834-4343-a770-3f544966f633"|"Which European city is at the same latitude as Ann Arbor?"|"{"choices":["Stockholm, Sweden","Berlin, Germany","London, England","Paris, France","Madrid, Spain"],"type":"MultipleChoice"}"|"{"solution":[4],"selectAll":false,"type":"MultipleChoice"}"|"2019-01-31 22:11:08.000"|"81392cd3-28e9-4e2e-8a33-018104b1f4d1"|"{"solution":[3,4],"type":"MultipleChoice"}"|"0"|"2db10c95-b507-4211-8244-394361148b22"|"Student"|"One"|"student1#umich.edu"|"Student"
"ee73fdaf-a926-4899-b0f7-9b942f1b44ad"|"6-Elbow, Wrist, Hand W19"|"48539109-529e-4359-83b9-2ae81be0532c"|"001"|"3b5b5e49-1798-4eab-86d7-186cf59149b4"|"MOVESCI 230"|"Human Musculoskeletal Anatomy"|"fcd7c673-d944-48c3-8a09-f458e03f8c44"|"What is the name of this movement?"|"{"choices":["first phalangeal joint","first proximal interphalangeal joint","first distal interphalangeal joint","first interphalangeal joint"],"type":"MultipleChoice"}"|"{"solution":[3],"selectAll":false,"type":"MultipleChoice"}"|"2019-01-31 22:07:32.000"|"9016f36c-41f5-4e14-84a9-78eea682c802"|"{"solution":[3],"type":"MultipleChoice"}"|"1"|"7184708d-4dc7-42e0-b1ea-4aca51f00fcd"|"Student"|"Two"|"student2#umich.edu"|"Student"
You are correct that the problem was the form of the CSV file.
I changed readCSV = csv.reader(csvfile) to readCSV = csv.reader(csvfile, delimiter="|", quotechar='|')
I then took the resulting list and removed the extraneous quotation marks from each element.
The rest of the program now works properly.

How to sum map values based on two keys?

I have a map with two keys (customer and price) like the one shown below:
[
customer: ['Clinton', 'Clinton', 'Mark', 'Antony', 'Clinton', 'Mark'],
price: [15000.0, 27000.0, 28000.0, 56000.0, 21000.0, 61000.0]
]
customer and price values are mapped by their index positione i.e first name from customer list maps with the first price and so on.
Example
Cliton price is 15000.0
Cliton price 27000.0
Mark price 28000.0
Antony price 56000.0
Clinton price 21000.0
Mark price 61000.0
I would like to sum up price grouped by names. Expected output:
Clinton price 63000
Mark price 89000
Antony price 56000
Are there any built-in functions to achieve this in Groovy, or do I need to iterate over the map and sum values by writing my own functions?
You can start with a transpose on both lists to get tuples of customer and price. From there its basically like the other answers (group by customer, build map with customer and summed up prices). E.g.:
def data = [
customer:['Clinton', 'Clinton', 'Mark', 'Antony', 'Clinton', 'Mark'],
price:[15000.0, 27000.0, 28000.0, 56000.0, 21000.0, 61000.0]
]
println(
[data.customer, data.price].transpose().groupBy{ c, p -> c }.collectEntries{ c, ps -> [c, ps*.last().sum() ] }
)
// => [Clinton:63000.0, Mark:89000.0, Antony:56000.0]
In the problems like this, we should always plan having every entry as separate object inside a list to make it intuitive and future easy manipulation in the list.
In that case the same result can be obtained in naturally
def list = [
[customer: 'Clinton', price: 15000.0],
[customer: 'Clinton', price: 27000.0],
[customer: 'Mark', price: 28000.0],
[customer: 'Antony', price: 56000.0],
[customer: 'Clinton', price: 21000.0],
[customer: 'Mark', price: 61000.0]
]
def map = list.groupBy({it.customer}).collectEntries {k, v -> [k, v.price.sum()]}
map.each {println it}
The followint creates a map of price aggregated by customer:
def vals = (0..(-1+map.customer.size()))
.collect{['name':map.customer[it], 'price': map.price[it]]}
.groupBy{it['name']}
.collectEntries{[(it.key): it.value.collect{it['price']}.sum()]}
That results in:
[Clinton:63000.0, Mark:89000.0, Antony:56000.0]
It's essentially an iteration using a range of numbers from 0 to map.customer.size() - 1, followed by a group-by with sum of values.
This version is derived from #cfrick's answer, with an alternative to the summation. Using a map with default values isn't as "functional"/declarative, but IMHO the code is arguably easier to grok later (i.e. maintenance):
Given:
def map = [
customer: ['Clinton', 'Clinton', 'Mark', 'Antony', 'Clinton', 'Mark'],
price: [15000.0, 27000.0, 28000.0, 56000.0, 21000.0, 61000.0]
]
Approach:
def getSumMap = { data ->
def result = [:].withDefault { c -> 0.0 }
[data.customer, data.price].transpose().each { c, p -> result[c] += p }
result
}
assert 63000.0 == getSumMap(map)['Clinton']
assert 89000.0 == getSumMap(map)['Mark']
assert 56000.0 == getSumMap(map)['Antony']

Specific string sorting [Python 2.7]

I am fairly new to python, and I was trying to sort this string in a certain way (Taken off a database):
6392079|||| 1.0|03/09/2017|PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP|INSULIN INFUSION PUMP / SENSOR AUGMENTED|MEDTRONIC MINIMED|18000 DEVONSHIRE STREET||NORTHRIDGE|CA|91325||US|91325||MMT-723LNAH|MMT-723LNAH|||0LP|R|01/29/2014|OYC||Y
This is the standard format for these types of strings:
MDR_REPORT_KEY|DEVICE_EVENT_KEY|IMPLANT_FLAG|DATE_REMOVED_FLAG|DEVICE_SEQUENCE_NO|DATE_RECEIVED|BRAND_NAME|GENERIC_NAME|MANUFACTURER_D_NAME|MANUFACTURER_D_ADDRESS_1|MANUFACTURER_D_ADDRESS_2|MANUFACTURER_D_CITY|MANUFACTURER_D_STATE_CODE|MANUFACTURER_D_ZIP_CODE|MANUFACTURER_D_ZIP_CODE_EXT|MANUFACTURER_D_COUNTRY_CODE|MANUFACTURER_D_POSTAL_CODE|EXPIRATION_DATE_OF_DEVICE|MODEL_NUMBER|CATALOG_NUMBER|LOT_NUMBER|OTHER_ID_NUMBER|DEVICE_OPERATOR|DEVICE_AVAILABILITY|DATE_RETURNED_TO_MANUFACTURER|DEVICE_REPORT_PRODUCT_CODE|DEVICE_AGE_TEXT|DEVICE_EVALUATED_BY_MANUFACTUR
Is there any way I can print out this string sorted with the specific datatype next to the value?
For example as an output I would like to have
Report key: 6392079
Device sequence number: 1.0
Date received: 03/09/2017
Brand name: PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP
etc.etc. with the other values. I think I would need to use the "|" as a divider to separate the data, but I'm not sure how to. I also cannot use sorting with the index number, because there are many variations of the string above which are all different lengths.
Also as you can see in the string some of the data such as device_event_key, implant_flag, date_removed_flag, and device_sequence number are absent, but there are still corresponding empty vertical slashes.
Any help would be greatly appreciated, thanks.
#nsortur, you can try the below code to get the output.
I have used the concept of list comprehension, zip() function and split(), join() methods defined on string objects.
You can try to run code online at
http://rextester.com/MBDXB29573 (Code perfectly works with Python2/Python3).
string1 = "6392079|||| 1.0|03/09/2017|PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP|INSULIN INFUSION PUMP / SENSOR AUGMENTED|MEDTRONIC MINIMED|18000 DEVONSHIRE STREET||NORTHRIDGE|CA|91325||US|91325||MMT-723LNAH|MMT-723LNAH|||0LP|R|01/29/2014|OYC||Y"
keys = ["Report key", "Device sequence number","Date received", "Brand name"];
values = [key.strip() for key in string1.split("|") if key.strip()];
output = "\n".join([key + ": " + str(value) for key, value in zip(keys, values)]);
print(output);
Output:
Report key: 6392079
Device sequence number: 1.0
Date received: 03/09/2017
Brand name: PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP
Use zip to merge the two lists into tuple pairs:
data = '6392079|||| 1.0|03/09/2017|PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP|INSULIN INFUSION PUMP / SENSOR AUGMENTED|MEDTRONIC MINIMED|18000 DEVONSHIRE STREET||NORTHRIDGE|CA|91325||US|91325||MMT-723LNAH|MMT-723LNAH|||0LP|R|01/29/2014|OYC||Y'
format = 'MDR_REPORT_KEY|DEVICE_EVENT_KEY|IMPLANT_FLAG|DATE_REMOVED_FLAG|DEVICE_SEQUENCE_NO|DATE_RECEIVED|BRAND_NAME|GENERIC_NAME|MANUFACTURER_D_NAME|MANUFACTURER_D_ADDRESS_1|MANUFACTURER_D_ADDRESS_2|MANUFACTURER_D_CITY|MANUFACTURER_D_STATE_CODE|MANUFACTURER_D_ZIP_CODE|MANUFACTURER_D_ZIP_CODE_EXT|MANUFACTURER_D_COUNTRY_CODE|MANUFACTURER_D_POSTAL_CODE|EXPIRATION_DATE_OF_DEVICE|MODEL_NUMBER|CATALOG_NUMBER|LOT_NUMBER|OTHER_ID_NUMBER|DEVICE_OPERATOR|DEVICE_AVAILABILITY|DATE_RETURNED_TO_MANUFACTURER|DEVICE_REPORT_PRODUCT_CODE|DEVICE_AGE_TEXT|DEVICE_EVALUATED_BY_MANUFACTUR'
for label, value in zip(format.split('|'), data.split('|')):
print("%s: %s" % (label.replace('_', ' ').capitalize(), value))
This outputs:
Mdr report key: 6392079
Device event key:
Implant flag:
Date removed flag:
Device sequence no: 1.0
Date received: 03/09/2017
Brand name: PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP
Generic name: INSULIN INFUSION PUMP / SENSOR AUGMENTED
Manufacturer d name: MEDTRONIC MINIMED
Manufacturer d address 1: 18000 DEVONSHIRE STREET
Manufacturer d address 2:
Manufacturer d city: NORTHRIDGE
Manufacturer d state code: CA
Manufacturer d zip code: 91325
Manufacturer d zip code ext:
Manufacturer d country code: US
Manufacturer d postal code: 91325
Expiration date of device:
Model number: MMT-723LNAH
Catalog number: MMT-723LNAH
Lot number:
Other id number:
Device operator: 0LP
Device availability: R
Date returned to manufacturer: 01/29/2014
Device report product code: OYC
Device age text:
Device evaluated by manufactur: Y
This can be achieved by simple split() method of the str, split('|') would have empty strings for the empty values between two |, and then match it with dict having attribute as key and value as value of dict
query = '6392079|||| 1.0|03/09/2017|PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP|INSULIN INFUSION PUMP / SENSOR AUGMENTED|MEDTRONIC MINIMED|18000 DEVONSHIRE STREET||NORTHRIDGE|CA|91325||US|91325||MMT-723LNAH|MMT-723LNAH|||0LP|R|01/29/2014|OYC||Y'
def get_detail(str_):
key_finder = {'Report Key': 0, 'Device Sequence Number': 4, 'Device Recieved': 5, 'Brand Name': 6}
split_by = str_.split('|')
print('Report Key : {}'.format(split_by[key_finder['Report Key']]))
print('Device Seq Num : {}'.format(split_by[key_finder['Device Sequence Number']]))
print('Device Recieved : {}'.format(split_by[key_finder['Device Recieved']]))
print('Brand Name : {}'.format(split_by[key_finder['Brand Name']]))
>>> get_detail(query)
Report Key : 6392079
Device Seq Num : 1.0
Device Recieved : 03/09/2017
Brand Name : PARADIGM REAL-TIME REVEL INSULIN INFUSION PUMP
This works because the splited string will be indexed from 0, so the Report Key will have the value in 0th index of the splitted string and so on for other values. This will be matched with the dict key_finder which has the stored index for each value.

Resources