问:
Python parse output of mixed format text file to key value pair dictionaries
I am trying to parse the output of a command from the EMC OneFS CLI. We are trying to collect inventory data, and since we're on an older version of the API we can't use the REST SDK.

Instead we have decided to do it the "hacky" way and parse the output of CLI commands.

How can I reliably parse this data in Python, given the varying formats of text? Notice the varying amounts of white space, and the fact that some of these are separated by : while others are separated by =.

I have a decent start on this, I was able to split up each line into a list and handle the cases where the = sign is nested within parenthesis.

I am still stuck on the other parts:

Take the first column as the "hostname"

Build a separate dictionary for each hostname that contains all key value pairs (some are separated by : others are separated by =)

RAW OUTPUT THAT NEEDS TO BE PARSED:

```<code>visi-91:   SerNo: S123456789P
visi-91:  Config: 912-111-231
visi-91:   Class: storage
visi-91:  Series: x_series
visi-91: Product: IQ 32000x-ssd
visi-91: Comps:  Chassis CPU     Motherboard     NVRam   FlashDrive      Disk_Controller Disk_Expander   Power_Supplies
visi-91:   HWGen: MaunaLoa (MaunaLoa Hardware)
visi-91: Chassis: ISI36 (Isilon (CIDesigns) 36-Bay Chassis)
visi-91:     CPU: GenuineIntel (2.33GHz, stepping 0x0001067a)
visi-91:    PROC: Dual-proc, Quad-core
visi-91:     RAM: 17150812160 Bytes
visi-91:    Mobo: SupMicX7DBU (SuperMicro X7DBU Motherboard)
visi-91:   NVRam: MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)
visi-91: FlshDrv: None (No physical dongle supported) ((null))
visi-91:  DskCtl: LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)
visi-91:  DskExp: VIT7156 (Vitesse 7156 Disk Expander)
visi-91: PwrSupl: PS1 (type=Emerson, fw=v.01.00.00)
visi-91: PwrSupl: PS2 (type=Emerson, fw=v.01.00.00)
visi-91: ChasCnt: 1 (Single-Chassis System)
visi-91:   NetIF: em*4,ib*2 (4x Intel, 2x IB)
visi-91:  IBType: ISI25208 (Isilon MT25208-based IB Card)
visi-91:  LCDver: NoriVFD (Noritake VFD)
visi-91:     IMB: Board Version 0x20f
visi-91: Power Supplies OK
visi-91: CPU Operation (raw 0x882F0000)  = Normal
visi-91: CPU Speed Limit                 = 100.00%
visi-91: Chassis Fan1 (ISI F1)           = 7469
visi-91: Chassis Fan2 (ISI F2)           = 7552
visi-91: Chassis Fan3 (ISI F3)           = 7387
visi-91: Power Supply 1 Fan              = 5504
visi-91: Power Supply 2 Fan              = 5792
visi-91: Temp Until CPU Throttle (CPU 0) = 46.0
visi-91: Temp Until CPU Throttle (CPU 1) = 42.0
visi-91: Temp Front Panel                = 17.0
visi-91: Temp Chassis 2 (ISI T2)         = 22.0
visi-91: Temp System                     = 25.0
visi-92:   SerNo: S123456785K
visi-92:  Config: 912-111-231
visi-92:   Class: storage
visi-92:  Series: x_series
visi-92: Product: IQ 32000x-ssd
visi-92: Comps:  Chassis CPU     Motherboard     NVRam   FlashDrive      Disk_Controller Disk_Expander   Power_Supplies
visi-92:   HWGen: MaunaLoa (MaunaLoa Hardware)
visi-92: Chassis: ISI36 (Isilon (CIDesigns) 36-Bay Chassis)
visi-92:     CPU: GenuineIntel (2.33GHz, stepping 0x0001067a)
visi-92:    PROC: Dual-proc, Quad-core
visi-92:     RAM: 17150812160 Bytes
visi-92:    Mobo: SupMicX7DBU (SuperMicro X7DBU Motherboard)
visi-92:   NVRam: MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)
visi-92: FlshDrv: None (No physical dongle supported) ((null))
visi-92:  DskCtl: LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)
visi-92:  DskExp: VIT7156 (Vitesse 7156 Disk Expander)
visi-92: PwrSupl: PS1 (type=Emerson, fw=v.01.00.00)
visi-92: PwrSupl: PS2 (type=Emerson, fw=v.01.00.00)
visi-92: ChasCnt: 1 (Single-Chassis System)
visi-92:   NetIF: em*4,ib*2 (4x Intel, 2x IB)
visi-92:  IBType: ISI25208 (Isilon MT25208-based IB Card)
visi-92:  LCDver: NoriVFD (Noritake VFD)
visi-92:     IMB: Board Version 0x20f
visi-92: Power Supplies OK
visi-92: CPU Operation (raw 0x882E0000)  = Normal
visi-92: CPU Speed Limit                 = 100.00%
visi-92: Chassis Fan1 (ISI F1)           = 7268
visi-92: Chassis Fan2 (ISI F2)           = 7307
visi-92: Chassis Fan3 (ISI F3)           = 7190
visi-92: Power Supply 1 Fan              = 5376
visi-92: Power Supply 2 Fan              = 5696
visi-92: Temp Until CPU Throttle (CPU 0) = 46.0
visi-92: Temp Until CPU Throttle (CPU 1) = 46.0
visi-92: Temp Front Panel                = 17.2
visi-92: Temp Chassis 2 (ISI T2)         = 24.0
visi-92: Temp System                     = 27.0
visi-93:   SerNo: S987654321P
visi-93:  Config: 912-111-231
visi-93:   Class: storage
visi-93:  Series: x_series
visi-93: Product: IQ 32000x-ssd
visi-93: Comps:  Chassis CPU     Motherboard     NVRam   FlashDrive      Disk_Controller Disk_Expander   Power_Supplies
visi-93:   HWGen: MaunaLoa (MaunaLoa Hardware)
visi-93: Chassis: ISI36 (Isilon (CIDesigns) 36-Bay Chassis)
visi-93:     CPU: GenuineIntel (2.33GHz, stepping 0x0001067a)
visi-93:    PROC: Dual-proc, Quad-core
visi-93:     RAM: 17150812160 Bytes
visi-93:    Mobo: SupMicX7DBU (SuperMicro X7DBU Motherboard)
visi-93:   NVRam: MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)
visi-93: FlshDrv: None (No physical dongle supported) ((null))
visi-93:  DskCtl: LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)
visi-93:  DskExp: VIT7156 (Vitesse 7156 Disk Expander)
visi-93: PwrSupl: PS1 (type=Emerson, fw=v.03.05.00)
visi-93: PwrSupl: PS2 (type=Emerson, fw=v.03.05.00)
visi-93: ChasCnt: 1 (Single-Chassis System)
visi-93:   NetIF: em*4,ib*2 (4x Intel, 2x IB)
visi-93:  IBType: ISI25208 (Isilon MT25208-based IB Card)
visi-93:  LCDver: NoriVFD (Noritake VFD)
visi-93:     IMB: Board Version 0x20f
visi-93: Power Supplies OK
visi-93: CPU Operation (raw 0x88250000)  = Normal
visi-93: CPU Speed Limit                 = 100.00%
visi-93: Chassis Fan1 (ISI F1)           = 7387
visi-93: Chassis Fan2 (ISI F2)           = 7152
visi-93: Chassis Fan3 (ISI F3)           = 7152
visi-93: Power Supply 1 Fan              = 8512
visi-93: Power Supply 2 Fan              = 8512
visi-93: Temp Until CPU Throttle (CPU 0) = 37.0
visi-93: Temp Until CPU Throttle (CPU 1) = 38.0
visi-93: Temp Front Panel                = 17.4
visi-93: Temp Chassis 2 (ISI T2)         = 25.0
visi-93: Temp System                     = 28.0
</code>```

MY CODE SO FAR:

```<code>#Read text file
file = open("test_itry.txt", "r")
lines = file.readlines()
file.close()

for line in lines:
    #Remove whitespaces
    line = line.replace(' ','')
    #Remove newlines
    line = line.replace('\n','')
    #Handler values that have equals signs nested within parenthesis
    #If line has closed parenthesis and equals sign
    if line.count(")") > 0 and line.count("=") > 0:
        #Get first position of open parenthesis
        poscp = line.find(")")
        #Get first position of equals sign
        poseq = line.find("=")
        #If position of equals sign comes before position of first parenthesis
        if poscp < poseq:
            #Split by first equals sign
            line = line.split("=", 1)
    #If line doesn't have closed parenthesis and an equals sign
    else:
        line = line.split("=", 1)
    #If line has not been split into a list yet create a list
    if isinstance(line, str):
        line = line.split()
    print(line)
</code>```

OUTPUT OF MY CODE SO FAR:

```<code>['visi-91:SerNo:S123456789P']
['visi-91:Config:912-111-231']
['visi-91:Class:storage']
['visi-91:Series:x_series']
['visi-91:Product:IQ32000x-ssd']
['visi-91:Comps:ChassisCPUMotherboardNVRamFlashDriveDisk_ControllerDisk_ExpanderPower_Supplies']
['visi-91:HWGen:MaunaLoa(MaunaLoaHardware)']
['visi-91:Chassis:ISI36(Isilon(CIDesigns)36-BayChassis)']
['visi-91:CPU:GenuineIntel(2.33GHz,stepping0x0001067a)']
['visi-91:PROC:Dual-proc,Quad-core']
['visi-91:RAM:17150812160Bytes']
['visi-91:Mobo:SupMicX7DBU(SuperMicroX7DBUMotherboard)']
['visi-91:NVRam:MT25208(Mellanox25208basedCard)(492MBcard)(size515899392B)']
['visi-91:FlshDrv:None(Nophysicaldonglesupported)((null))']
['visi-91:DskCtl:LSI3081E-HBA(LSISAS3081ESASController--HBA)(8ports)']
['visi-91:DskExp:VIT7156(Vitesse7156DiskExpander)']
['visi-91:PwrSupl:PS1(type=Emerson,fw=v.01.00.00)']
['visi-91:PwrSupl:PS2(type=Emerson,fw=v.01.00.00)']
['visi-91:ChasCnt:1(Single-ChassisSystem)']
['visi-91:NetIF:em*4,ib*2(4xIntel,2xIB)']
['visi-91:IBType:ISI25208(IsilonMT25208-basedIBCard)']
['visi-91:LCDver:NoriVFD(NoritakeVFD)']
['visi-91:IMB:BoardVersion0x20f']
['visi-91:PowerSuppliesOK']
['visi-91:CPUOperation(raw0x882F0000)', 'Normal']
['visi-91:CPUSpeedLimit', '100.00%']
['visi-91:ChassisFan1(ISIF1)', '7469']
['visi-91:ChassisFan2(ISIF2)', '7552']
['visi-91:ChassisFan3(ISIF3)', '7387']
['visi-91:PowerSupply1Fan', '5504']
['visi-91:PowerSupply2Fan', '5792']
['visi-91:TempUntilCPUThrottle(CPU0)', '46.0']
['visi-91:TempUntilCPUThrottle(CPU1)', '42.0']
['visi-91:TempFrontPanel', '17.0']
['visi-91:TempChassis2(ISIT2)', '22.0']
['visi-91:TempSystem', '25.0']
['visi-92:SerNo:S123456785K']
['visi-92:Config:912-111-231']
['visi-92:Class:storage']
['visi-92:Series:x_series']
['visi-92:Product:IQ32000x-ssd']
['visi-92:Comps:ChassisCPUMotherboardNVRamFlashDriveDisk_ControllerDisk_ExpanderPower_Supplies']
['visi-92:HWGen:MaunaLoa(MaunaLoaHardware)']
['visi-92:Chassis:ISI36(Isilon(CIDesigns)36-BayChassis)']
['visi-92:CPU:GenuineIntel(2.33GHz,stepping0x0001067a)']
['visi-92:PROC:Dual-proc,Quad-core']
['visi-92:RAM:17150812160Bytes']
['visi-92:Mobo:SupMicX7DBU(SuperMicroX7DBUMotherboard)']
['visi-92:NVRam:MT25208(Mellanox25208basedCard)(492MBcard)(size515899392B)']
['visi-92:FlshDrv:None(Nophysicaldonglesupported)((null))']
['visi-92:DskCtl:LSI3081E-HBA(LSISAS3081ESASController--HBA)(8ports)']
['visi-92:DskExp:VIT7156(Vitesse7156DiskExpander)']
['visi-92:PwrSupl:PS1(type=Emerson,fw=v.01.00.00)']
['visi-92:PwrSupl:PS2(type=Emerson,fw=v.01.00.00)']
['visi-92:ChasCnt:1(Single-ChassisSystem)']
['visi-92:NetIF:em*4,ib*2(4xIntel,2xIB)']
['visi-92:IBType:ISI25208(IsilonMT25208-basedIBCard)']
['visi-92:LCDver:NoriVFD(NoritakeVFD)']
['visi-92:IMB:BoardVersion0x20f']
['visi-92:PowerSuppliesOK']
['visi-92:CPUOperation(raw0x882E0000)', 'Normal']
['visi-92:CPUSpeedLimit', '100.00%']
['visi-92:ChassisFan1(ISIF1)', '7268']
['visi-92:ChassisFan2(ISIF2)', '7307']
['visi-92:ChassisFan3(ISIF3)', '7190']
['visi-92:PowerSupply1Fan', '5376']
['visi-92:PowerSupply2Fan', '5696']
['visi-92:TempUntilCPUThrottle(CPU0)', '46.0']
['visi-92:TempUntilCPUThrottle(CPU1)', '46.0']
['visi-92:TempFrontPanel', '17.2']
['visi-92:TempChassis2(ISIT2)', '24.0']
['visi-92:TempSystem', '27.0']
['visi-93:SerNo:S987654321P']
['visi-93:Config:912-111-231']
['visi-93:Class:storage']
['visi-93:Series:x_series']
['visi-93:Product:IQ32000x-ssd']
['visi-93:Comps:ChassisCPUMotherboardNVRamFlashDriveDisk_ControllerDisk_ExpanderPower_Supplies']
['visi-93:HWGen:MaunaLoa(MaunaLoaHardware)']
['visi-93:Chassis:ISI36(Isilon(CIDesigns)36-BayChassis)']
['visi-93:CPU:GenuineIntel(2.33GHz,stepping0x0001067a)']
['visi-93:PROC:Dual-proc,Quad-core']
['visi-93:RAM:17150812160Bytes']
['visi-93:Mobo:SupMicX7DBU(SuperMicroX7DBUMotherboard)']
['visi-93:NVRam:MT25208(Mellanox25208basedCard)(492MBcard)(size515899392B)']
['visi-93:FlshDrv:None(Nophysicaldonglesupported)((null))']
['visi-93:DskCtl:LSI3081E-HBA(LSISAS3081ESASController--HBA)(8ports)']
['visi-93:DskExp:VIT7156(Vitesse7156DiskExpander)']
['visi-93:PwrSupl:PS1(type=Emerson,fw=v.03.05.00)']
['visi-93:PwrSupl:PS2(type=Emerson,fw=v.03.05.00)']
['visi-93:ChasCnt:1(Single-ChassisSystem)']
['visi-93:NetIF:em*4,ib*2(4xIntel,2xIB)']
['visi-93:IBType:ISI25208(IsilonMT25208-basedIBCard)']
['visi-93:LCDver:NoriVFD(NoritakeVFD)']
['visi-93:IMB:BoardVersion0x20f']
['visi-93:PowerSuppliesOK']
['visi-93:CPUOperation(raw0x88250000)', 'Normal']
['visi-93:CPUSpeedLimit', '100.00%']
['visi-93:ChassisFan1(ISIF1)', '7387']
['visi-93:ChassisFan2(ISIF2)', '7152']
['visi-93:ChassisFan3(ISIF3)', '7152']
['visi-93:PowerSupply1Fan', '8512']
['visi-93:PowerSupply2Fan', '8512']
['visi-93:TempUntilCPUThrottle(CPU0)', '37.0']
['visi-93:TempUntilCPUThrottle(CPU1)', '38.0']
['visi-93:TempFrontPanel', '17.4']
['visi-93:TempChassis2(ISIT2)', '25.0']
['visi-93:TempSystem', '28.0']
</code>```

DESIRED OUTPUT - Dictionary key/value pairs with first word as hostname.
Separate dictionaries for each hostname:

```<code>{'hostname':'visi-91', 'SerNo':'S123456789P', 'Config':'912-111-231', 'Class':'storage', 'Series':'x_series', 'PwrSupl':'PS1(type=Emerson,fw=v.01.00.00)', 'Chassis':'ISI36(Isilon(CIDesigns)36-BayChassis)', 'NetIF':'em*4,ib*2(4xIntel,2xIB)', 'IBType':'ISI25208(IsilonMT25208-basedIBCard)'} //etc...

{'hostname':'visi-92', 'SerNo':'S123456785K', 'Config':'912-111-231', 'Class':'storage', 'Series':'x_series', 'PwrSupl':'PS1(type=Emerson,fw=v.01.00.00)' 'Chassis':'ISI36(Isilon(CIDesigns)36-BayChassis)', 'NetIF':'em*4,ib*2(4xIntel,2xIB)', 'IBType':'ISI25208(IsilonMT25208-basedIBCard)'}  //etc...
</code>```

答:
I think the best way would be to use re.match():

#!/usr/bin/env python2.7

import re

results = {}

with open('in.txt', 'r') as f:
    for line in [ l.rstrip() for l in f.readlines() ]:
        match = re.match('^(?P<hostname>[^:]+): +(?P<key>[^:=]+?)(?: *[:=] *(?P<value>.+?) *)?$', line)

        if match is None:
            # skip failed matches
            #print(line)
            continue

        hostname, key, value = match.groups()

        if key == 'Comps':
            value = [ x.strip() for x in re.sub('  +',' ',value).split(' ') ]
        else:
            try:
                value = float(value)
            except:
                pass

        if hostname not in results:
            results[hostname] = {}

        if key in results[hostname]:
            old_value = results[hostname][key]
            if isinstance(old_value, list):
                old_value.append(value)
            else:
                results[hostname][key] = [ old_value, value ]
        else:
            results[hostname][key] = value

from pprint import pprint
pprint(results)
```

<p>I've also taken some liberties:</p>

<ul>
<li>Proposed an alternative result format <code>results[hostname][key]</code></li>
<li>Converted the <code>'Comps'</code> data into an array</li>
<li>Converted anything that will be converted as a <code>float</code>, into a number</li>
</ul>

<p>Output is like this:</p>

<pre class="lang-py prettyprint-override"><code>{'visi-91': {'CPU': 'GenuineIntel (2.33GHz, stepping 0x0001067a)',
             'CPU Operation (raw 0x882F0000)': 'Normal',
             'CPU Speed Limit': '100.00%',
             'ChasCnt': '1 (Single-Chassis System)',
             'Chassis': 'ISI36 (Isilon (CIDesigns) 36-Bay Chassis)',
             'Chassis Fan1 (ISI F1)': 7469.0,
             'Chassis Fan2 (ISI F2)': 7552.0,
             'Chassis Fan3 (ISI F3)': 7387.0,
             'Class': 'storage',
             'Comps': ['Chassis',
                       'CPU',
                       'Motherboard',
                       'NVRam',
                       'FlashDrive',
                       'Disk_Controller',
                       'Disk_Expander',
                       'Power_Supplies'],
             'Config': '912-111-231',
             'DskCtl': 'LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)',
             'DskExp': 'VIT7156 (Vitesse 7156 Disk Expander)',
             'FlshDrv': 'None (No physical dongle supported) ((null))',
             'HWGen': 'MaunaLoa (MaunaLoa Hardware)',
             'IBType': 'ISI25208 (Isilon MT25208-based IB Card)',
             'IMB': 'Board Version 0x20f',
             'LCDver': 'NoriVFD (Noritake VFD)',
             'Mobo': 'SupMicX7DBU (SuperMicro X7DBU Motherboard)',
             'NVRam': 'MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)',
             'NetIF': 'em*4,ib*2 (4x Intel, 2x IB)',
             'PROC': 'Dual-proc, Quad-core',
             'Power Supplies OK': None,
             'Power Supply 1 Fan': 5504.0,
             'Power Supply 2 Fan': 5792.0,
             'Product': 'IQ 32000x-ssd',
             'PwrSupl': ['PS1 (type=Emerson, fw=v.01.00.00)',
                         'PS2 (type=Emerson, fw=v.01.00.00)'],
             'RAM': '17150812160 Bytes',
             'SerNo': 'S123456789P',
             'Series': 'x_series',
             'Temp Chassis 2 (ISI T2)': 22.0,
             'Temp Front Panel': 17.0,
             'Temp System': 25.0,
             'Temp Until CPU Throttle (CPU 0)': 46.0,
             'Temp Until CPU Throttle (CPU 1)': 42.0},
 'visi-92': {'CPU': 'GenuineIntel (2.33GHz, stepping 0x0001067a)',
             'CPU Operation (raw 0x882E0000)': 'Normal',
             'CPU Speed Limit': '100.00%',
             'ChasCnt': '1 (Single-Chassis System)',
             'Chassis': 'ISI36 (Isilon (CIDesigns) 36-Bay Chassis)',
             'Chassis Fan1 (ISI F1)': 7268.0,
             'Chassis Fan2 (ISI F2)': 7307.0,
             'Chassis Fan3 (ISI F3)': 7190.0,
             'Class': 'storage',
             'Comps': ['Chassis',
                       'CPU',
                       'Motherboard',
                       'NVRam',
                       'FlashDrive',
                       'Disk_Controller',
                       'Disk_Expander',
                       'Power_Supplies'],
             'Config': '912-111-231',
             'DskCtl': 'LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)',
             'DskExp': 'VIT7156 (Vitesse 7156 Disk Expander)',
             'FlshDrv': 'None (No physical dongle supported) ((null))',
             'HWGen': 'MaunaLoa (MaunaLoa Hardware)',
             'IBType': 'ISI25208 (Isilon MT25208-based IB Card)',
             'IMB': 'Board Version 0x20f',
             'LCDver': 'NoriVFD (Noritake VFD)',
             'Mobo': 'SupMicX7DBU (SuperMicro X7DBU Motherboard)',
             'NVRam': 'MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)',
             'NetIF': 'em*4,ib*2 (4x Intel, 2x IB)',
             'PROC': 'Dual-proc, Quad-core',
             'Power Supplies OK': None,
             'Power Supply 1 Fan': 5376.0,
             'Power Supply 2 Fan': 5696.0,
             'Product': 'IQ 32000x-ssd',
             'PwrSupl': ['PS1 (type=Emerson, fw=v.01.00.00)',
                         'PS2 (type=Emerson, fw=v.01.00.00)'],
             'RAM': '17150812160 Bytes',
             'SerNo': 'S123456785K',
             'Series': 'x_series',
             'Temp Chassis 2 (ISI T2)': 24.0,
             'Temp Front Panel': 17.2,
             'Temp System': 27.0,
             'Temp Until CPU Throttle (CPU 0)': 46.0,
             'Temp Until CPU Throttle (CPU 1)': 46.0},
 'visi-93': {'CPU': 'GenuineIntel (2.33GHz, stepping 0x0001067a)',
             'CPU Operation (raw 0x88250000)': 'Normal',
             'CPU Speed Limit': '100.00%',
             'ChasCnt': '1 (Single-Chassis System)',
             'Chassis': 'ISI36 (Isilon (CIDesigns) 36-Bay Chassis)',
             'Chassis Fan1 (ISI F1)': 7387.0,
             'Chassis Fan2 (ISI F2)': 7152.0,
             'Chassis Fan3 (ISI F3)': 7152.0,
             'Class': 'storage',
             'Comps': ['Chassis',
                       'CPU',
                       'Motherboard',
                       'NVRam',
                       'FlashDrive',
                       'Disk_Controller',
                       'Disk_Expander',
                       'Power_Supplies'],
             'Config': '912-111-231',
             'DskCtl': 'LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)',
             'DskExp': 'VIT7156 (Vitesse 7156 Disk Expander)',
             'FlshDrv': 'None (No physical dongle supported) ((null))',
             'HWGen': 'MaunaLoa (MaunaLoa Hardware)',
             'IBType': 'ISI25208 (Isilon MT25208-based IB Card)',
             'IMB': 'Board Version 0x20f',
             'LCDver': 'NoriVFD (Noritake VFD)',
             'Mobo': 'SupMicX7DBU (SuperMicro X7DBU Motherboard)',
             'NVRam': 'MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)',
             'NetIF': 'em*4,ib*2 (4x Intel, 2x IB)',
             'PROC': 'Dual-proc, Quad-core',
             'Power Supplies OK': None,
             'Power Supply 1 Fan': 8512.0,
             'Power Supply 2 Fan': 8512.0,
             'Product': 'IQ 32000x-ssd',
             'PwrSupl': ['PS1 (type=Emerson, fw=v.03.05.00)',
                         'PS2 (type=Emerson, fw=v.03.05.00)'],
             'RAM': '17150812160 Bytes',
             'SerNo': 'S987654321P',
             'Series': 'x_series',
             'Temp Chassis 2 (ISI T2)': 25.0,
             'Temp Front Panel': 17.4,
             'Temp System': 28.0,
             'Temp Until CPU Throttle (CPU 0)': 37.0,
             'Temp Until CPU Throttle (CPU 1)': 38.0}}
</code>```

Edit: Now handles multiple occurrences of a given 'key', by forming an array (e.g: PwrSupl).

Body:
I am trying to parse the output of a command from the EMC OneFS CLI. We are trying to collect inventory data, and since we're on an older version of the API we can't use the REST SDK.

Instead we have decided to do it the "hacky" way and parse the output of CLI commands.

How can I reliably parse this data in Python, given the varying formats of text? Notice the varying amounts of white space, and the fact that some of these are separated by : while others are separated by =.

I have a decent start on this, I was able to split up each line into a list and handle the cases where the = sign is nested within parenthesis.

I am still stuck on the other parts:

Take the first column as the "hostname"

Build a separate dictionary for each hostname that contains all key value pairs (some are separated by : others are separated by =)

RAW OUTPUT THAT NEEDS TO BE PARSED:

visi-91:   SerNo: S123456789P
visi-91:  Config: 912-111-231
visi-91:   Class: storage
visi-91:  Series: x_series
visi-91: Product: IQ 32000x-ssd
visi-91: Comps:  Chassis CPU     Motherboard     NVRam   FlashDrive      Disk_Controller Disk_Expander   Power_Supplies
visi-91:   HWGen: MaunaLoa (MaunaLoa Hardware)
visi-91: Chassis: ISI36 (Isilon (CIDesigns) 36-Bay Chassis)
visi-91:     CPU: GenuineIntel (2.33GHz, stepping 0x0001067a)
visi-91:    PROC: Dual-proc, Quad-core
visi-91:     RAM: 17150812160 Bytes
visi-91:    Mobo: SupMicX7DBU (SuperMicro X7DBU Motherboard)
visi-91:   NVRam: MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)
visi-91: FlshDrv: None (No physical dongle supported) ((null))
visi-91:  DskCtl: LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)
visi-91:  DskExp: VIT7156 (Vitesse 7156 Disk Expander)
visi-91: PwrSupl: PS1 (type=Emerson, fw=v.01.00.00)
visi-91: PwrSupl: PS2 (type=Emerson, fw=v.01.00.00)
visi-91: ChasCnt: 1 (Single-Chassis System)
visi-91:   NetIF: em*4,ib*2 (4x Intel, 2x IB)
visi-91:  IBType: ISI25208 (Isilon MT25208-based IB Card)
visi-91:  LCDver: NoriVFD (Noritake VFD)
visi-91:     IMB: Board Version 0x20f
visi-91: Power Supplies OK
visi-91: CPU Operation (raw 0x882F0000)  = Normal
visi-91: CPU Speed Limit                 = 100.00%
visi-91: Chassis Fan1 (ISI F1)           = 7469
visi-91: Chassis Fan2 (ISI F2)           = 7552
visi-91: Chassis Fan3 (ISI F3)           = 7387
visi-91: Power Supply 1 Fan              = 5504
visi-91: Power Supply 2 Fan              = 5792
visi-91: Temp Until CPU Throttle (CPU 0) = 46.0
visi-91: Temp Until CPU Throttle (CPU 1) = 42.0
visi-91: Temp Front Panel                = 17.0
visi-91: Temp Chassis 2 (ISI T2)         = 22.0
visi-91: Temp System                     = 25.0
visi-92:   SerNo: S123456785K
visi-92:  Config: 912-111-231
visi-92:   Class: storage
visi-92:  Series: x_series
visi-92: Product: IQ 32000x-ssd
visi-92: Comps:  Chassis CPU     Motherboard     NVRam   FlashDrive      Disk_Controller Disk_Expander   Power_Supplies
visi-92:   HWGen: MaunaLoa (MaunaLoa Hardware)
visi-92: Chassis: ISI36 (Isilon (CIDesigns) 36-Bay Chassis)
visi-92:     CPU: GenuineIntel (2.33GHz, stepping 0x0001067a)
visi-92:    PROC: Dual-proc, Quad-core
visi-92:     RAM: 17150812160 Bytes
visi-92:    Mobo: SupMicX7DBU (SuperMicro X7DBU Motherboard)
visi-92:   NVRam: MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)
visi-92: FlshDrv: None (No physical dongle supported) ((null))
visi-92:  DskCtl: LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)
visi-92:  DskExp: VIT7156 (Vitesse 7156 Disk Expander)
visi-92: PwrSupl: PS1 (type=Emerson, fw=v.01.00.00)
visi-92: PwrSupl: PS2 (type=Emerson, fw=v.01.00.00)
visi-92: ChasCnt: 1 (Single-Chassis System)
visi-92:   NetIF: em*4,ib*2 (4x Intel, 2x IB)
visi-92:  IBType: ISI25208 (Isilon MT25208-based IB Card)
visi-92:  LCDver: NoriVFD (Noritake VFD)
visi-92:     IMB: Board Version 0x20f
visi-92: Power Supplies OK
visi-92: CPU Operation (raw 0x882E0000)  = Normal
visi-92: CPU Speed Limit                 = 100.00%
visi-92: Chassis Fan1 (ISI F1)           = 7268
visi-92: Chassis Fan2 (ISI F2)           = 7307
visi-92: Chassis Fan3 (ISI F3)           = 7190
visi-92: Power Supply 1 Fan              = 5376
visi-92: Power Supply 2 Fan              = 5696
visi-92: Temp Until CPU Throttle (CPU 0) = 46.0
visi-92: Temp Until CPU Throttle (CPU 1) = 46.0
visi-92: Temp Front Panel                = 17.2
visi-92: Temp Chassis 2 (ISI T2)         = 24.0
visi-92: Temp System                     = 27.0
visi-93:   SerNo: S987654321P
visi-93:  Config: 912-111-231
visi-93:   Class: storage
visi-93:  Series: x_series
visi-93: Product: IQ 32000x-ssd
visi-93: Comps:  Chassis CPU     Motherboard     NVRam   FlashDrive      Disk_Controller Disk_Expander   Power_Supplies
visi-93:   HWGen: MaunaLoa (MaunaLoa Hardware)
visi-93: Chassis: ISI36 (Isilon (CIDesigns) 36-Bay Chassis)
visi-93:     CPU: GenuineIntel (2.33GHz, stepping 0x0001067a)
visi-93:    PROC: Dual-proc, Quad-core
visi-93:     RAM: 17150812160 Bytes
visi-93:    Mobo: SupMicX7DBU (SuperMicro X7DBU Motherboard)
visi-93:   NVRam: MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)
visi-93: FlshDrv: None (No physical dongle supported) ((null))
visi-93:  DskCtl: LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)
visi-93:  DskExp: VIT7156 (Vitesse 7156 Disk Expander)
visi-93: PwrSupl: PS1 (type=Emerson, fw=v.03.05.00)
visi-93: PwrSupl: PS2 (type=Emerson, fw=v.03.05.00)
visi-93: ChasCnt: 1 (Single-Chassis System)
visi-93:   NetIF: em*4,ib*2 (4x Intel, 2x IB)
visi-93:  IBType: ISI25208 (Isilon MT25208-based IB Card)
visi-93:  LCDver: NoriVFD (Noritake VFD)
visi-93:     IMB: Board Version 0x20f
visi-93: Power Supplies OK
visi-93: CPU Operation (raw 0x88250000)  = Normal
visi-93: CPU Speed Limit                 = 100.00%
visi-93: Chassis Fan1 (ISI F1)           = 7387
visi-93: Chassis Fan2 (ISI F2)           = 7152
visi-93: Chassis Fan3 (ISI F3)           = 7152
visi-93: Power Supply 1 Fan              = 8512
visi-93: Power Supply 2 Fan              = 8512
visi-93: Temp Until CPU Throttle (CPU 0) = 37.0
visi-93: Temp Until CPU Throttle (CPU 1) = 38.0
visi-93: Temp Front Panel                = 17.4
visi-93: Temp Chassis 2 (ISI T2)         = 25.0
visi-93: Temp System                     = 28.0

MY CODE SO FAR:

#Read text file
file = open("test_itry.txt", "r")
lines = file.readlines()
file.close()

for line in lines:
    #Remove whitespaces
    line = line.replace(' ','')
    #Remove newlines
    line = line.replace('\n','')
    #Handler values that have equals signs nested within parenthesis
    #If line has closed parenthesis and equals sign
    if line.count(")") > 0 and line.count("=") > 0:
        #Get first position of open parenthesis
        poscp = line.find(")")
        #Get first position of equals sign
        poseq = line.find("=")
        #If position of equals sign comes before position of first parenthesis
        if poscp < poseq:
            #Split by first equals sign
            line = line.split("=", 1)
    #If line doesn't have closed parenthesis and an equals sign
    else:
        line = line.split("=", 1)
    #If line has not been split into a list yet create a list
    if isinstance(line, str):
        line = line.split()
    print(line)

OUTPUT OF MY CODE SO FAR:

['visi-91:SerNo:S123456789P']
['visi-91:Config:912-111-231']
['visi-91:Class:storage']
['visi-91:Series:x_series']
['visi-91:Product:IQ32000x-ssd']
['visi-91:Comps:ChassisCPUMotherboardNVRamFlashDriveDisk_ControllerDisk_ExpanderPower_Supplies']
['visi-91:HWGen:MaunaLoa(MaunaLoaHardware)']
['visi-91:Chassis:ISI36(Isilon(CIDesigns)36-BayChassis)']
['visi-91:CPU:GenuineIntel(2.33GHz,stepping0x0001067a)']
['visi-91:PROC:Dual-proc,Quad-core']
['visi-91:RAM:17150812160Bytes']
['visi-91:Mobo:SupMicX7DBU(SuperMicroX7DBUMotherboard)']
['visi-91:NVRam:MT25208(Mellanox25208basedCard)(492MBcard)(size515899392B)']
['visi-91:FlshDrv:None(Nophysicaldonglesupported)((null))']
['visi-91:DskCtl:LSI3081E-HBA(LSISAS3081ESASController--HBA)(8ports)']
['visi-91:DskExp:VIT7156(Vitesse7156DiskExpander)']
['visi-91:PwrSupl:PS1(type=Emerson,fw=v.01.00.00)']
['visi-91:PwrSupl:PS2(type=Emerson,fw=v.01.00.00)']
['visi-91:ChasCnt:1(Single-ChassisSystem)']
['visi-91:NetIF:em*4,ib*2(4xIntel,2xIB)']
['visi-91:IBType:ISI25208(IsilonMT25208-basedIBCard)']
['visi-91:LCDver:NoriVFD(NoritakeVFD)']
['visi-91:IMB:BoardVersion0x20f']
['visi-91:PowerSuppliesOK']
['visi-91:CPUOperation(raw0x882F0000)', 'Normal']
['visi-91:CPUSpeedLimit', '100.00%']
['visi-91:ChassisFan1(ISIF1)', '7469']
['visi-91:ChassisFan2(ISIF2)', '7552']
['visi-91:ChassisFan3(ISIF3)', '7387']
['visi-91:PowerSupply1Fan', '5504']
['visi-91:PowerSupply2Fan', '5792']
['visi-91:TempUntilCPUThrottle(CPU0)', '46.0']
['visi-91:TempUntilCPUThrottle(CPU1)', '42.0']
['visi-91:TempFrontPanel', '17.0']
['visi-91:TempChassis2(ISIT2)', '22.0']
['visi-91:TempSystem', '25.0']
['visi-92:SerNo:S123456785K']
['visi-92:Config:912-111-231']
['visi-92:Class:storage']
['visi-92:Series:x_series']
['visi-92:Product:IQ32000x-ssd']
['visi-92:Comps:ChassisCPUMotherboardNVRamFlashDriveDisk_ControllerDisk_ExpanderPower_Supplies']
['visi-92:HWGen:MaunaLoa(MaunaLoaHardware)']
['visi-92:Chassis:ISI36(Isilon(CIDesigns)36-BayChassis)']
['visi-92:CPU:GenuineIntel(2.33GHz,stepping0x0001067a)']
['visi-92:PROC:Dual-proc,Quad-core']
['visi-92:RAM:17150812160Bytes']
['visi-92:Mobo:SupMicX7DBU(SuperMicroX7DBUMotherboard)']
['visi-92:NVRam:MT25208(Mellanox25208basedCard)(492MBcard)(size515899392B)']
['visi-92:FlshDrv:None(Nophysicaldonglesupported)((null))']
['visi-92:DskCtl:LSI3081E-HBA(LSISAS3081ESASController--HBA)(8ports)']
['visi-92:DskExp:VIT7156(Vitesse7156DiskExpander)']
['visi-92:PwrSupl:PS1(type=Emerson,fw=v.01.00.00)']
['visi-92:PwrSupl:PS2(type=Emerson,fw=v.01.00.00)']
['visi-92:ChasCnt:1(Single-ChassisSystem)']
['visi-92:NetIF:em*4,ib*2(4xIntel,2xIB)']
['visi-92:IBType:ISI25208(IsilonMT25208-basedIBCard)']
['visi-92:LCDver:NoriVFD(NoritakeVFD)']
['visi-92:IMB:BoardVersion0x20f']
['visi-92:PowerSuppliesOK']
['visi-92:CPUOperation(raw0x882E0000)', 'Normal']
['visi-92:CPUSpeedLimit', '100.00%']
['visi-92:ChassisFan1(ISIF1)', '7268']
['visi-92:ChassisFan2(ISIF2)', '7307']
['visi-92:ChassisFan3(ISIF3)', '7190']
['visi-92:PowerSupply1Fan', '5376']
['visi-92:PowerSupply2Fan', '5696']
['visi-92:TempUntilCPUThrottle(CPU0)', '46.0']
['visi-92:TempUntilCPUThrottle(CPU1)', '46.0']
['visi-92:TempFrontPanel', '17.2']
['visi-92:TempChassis2(ISIT2)', '24.0']
['visi-92:TempSystem', '27.0']
['visi-93:SerNo:S987654321P']
['visi-93:Config:912-111-231']
['visi-93:Class:storage']
['visi-93:Series:x_series']
['visi-93:Product:IQ32000x-ssd']
['visi-93:Comps:ChassisCPUMotherboardNVRamFlashDriveDisk_ControllerDisk_ExpanderPower_Supplies']
['visi-93:HWGen:MaunaLoa(MaunaLoaHardware)']
['visi-93:Chassis:ISI36(Isilon(CIDesigns)36-BayChassis)']
['visi-93:CPU:GenuineIntel(2.33GHz,stepping0x0001067a)']
['visi-93:PROC:Dual-proc,Quad-core']
['visi-93:RAM:17150812160Bytes']
['visi-93:Mobo:SupMicX7DBU(SuperMicroX7DBUMotherboard)']
['visi-93:NVRam:MT25208(Mellanox25208basedCard)(492MBcard)(size515899392B)']
['visi-93:FlshDrv:None(Nophysicaldonglesupported)((null))']
['visi-93:DskCtl:LSI3081E-HBA(LSISAS3081ESASController--HBA)(8ports)']
['visi-93:DskExp:VIT7156(Vitesse7156DiskExpander)']
['visi-93:PwrSupl:PS1(type=Emerson,fw=v.03.05.00)']
['visi-93:PwrSupl:PS2(type=Emerson,fw=v.03.05.00)']
['visi-93:ChasCnt:1(Single-ChassisSystem)']
['visi-93:NetIF:em*4,ib*2(4xIntel,2xIB)']
['visi-93:IBType:ISI25208(IsilonMT25208-basedIBCard)']
['visi-93:LCDver:NoriVFD(NoritakeVFD)']
['visi-93:IMB:BoardVersion0x20f']
['visi-93:PowerSuppliesOK']
['visi-93:CPUOperation(raw0x88250000)', 'Normal']
['visi-93:CPUSpeedLimit', '100.00%']
['visi-93:ChassisFan1(ISIF1)', '7387']
['visi-93:ChassisFan2(ISIF2)', '7152']
['visi-93:ChassisFan3(ISIF3)', '7152']
['visi-93:PowerSupply1Fan', '8512']
['visi-93:PowerSupply2Fan', '8512']
['visi-93:TempUntilCPUThrottle(CPU0)', '37.0']
['visi-93:TempUntilCPUThrottle(CPU1)', '38.0']
['visi-93:TempFrontPanel', '17.4']
['visi-93:TempChassis2(ISIT2)', '25.0']
['visi-93:TempSystem', '28.0']

DESIRED OUTPUT - Dictionary key/value pairs with first word as hostname.
Separate dictionaries for each hostname:

{'hostname':'visi-91', 'SerNo':'S123456789P', 'Config':'912-111-231', 'Class':'storage', 'Series':'x_series', 'PwrSupl':'PS1(type=Emerson,fw=v.01.00.00)', 'Chassis':'ISI36(Isilon(CIDesigns)36-BayChassis)', 'NetIF':'em*4,ib*2(4xIntel,2xIB)', 'IBType':'ISI25208(IsilonMT25208-basedIBCard)'} //etc...

{'hostname':'visi-92', 'SerNo':'S123456785K', 'Config':'912-111-231', 'Class':'storage', 'Series':'x_series', 'PwrSupl':'PS1(type=Emerson,fw=v.01.00.00)' 'Chassis':'ISI36(Isilon(CIDesigns)36-BayChassis)', 'NetIF':'em*4,ib*2(4xIntel,2xIB)', 'IBType':'ISI25208(IsilonMT25208-basedIBCard)'}  //etc...

Body:
I think the best way would be to use re.match():

#!/usr/bin/env python2.7

import re

results = {}

with open('in.txt', 'r') as f:
    for line in [ l.rstrip() for l in f.readlines() ]:
        match = re.match('^(?P<hostname>[^:]+): +(?P<key>[^:=]+?)(?: *[:=] *(?P<value>.+?) *)?$', line)

        if match is None:
            # skip failed matches
            #print(line)
            continue

        hostname, key, value = match.groups()

        if key == 'Comps':
            value = [ x.strip() for x in re.sub('  +',' ',value).split(' ') ]
        else:
            try:
                value = float(value)
            except:
                pass

        if hostname not in results:
            results[hostname] = {}

        if key in results[hostname]:
            old_value = results[hostname][key]
            if isinstance(old_value, list):
                old_value.append(value)
            else:
                results[hostname][key] = [ old_value, value ]
        else:
            results[hostname][key] = value

from pprint import pprint
pprint(results)

I've also taken some liberties:

Proposed an alternative result format results[hostname][key]

Converted the 'Comps' data into an array

Converted anything that will be converted as a float, into a number

Output is like this:

{'visi-91': {'CPU': 'GenuineIntel (2.33GHz, stepping 0x0001067a)',
             'CPU Operation (raw 0x882F0000)': 'Normal',
             'CPU Speed Limit': '100.00%',
             'ChasCnt': '1 (Single-Chassis System)',
             'Chassis': 'ISI36 (Isilon (CIDesigns) 36-Bay Chassis)',
             'Chassis Fan1 (ISI F1)': 7469.0,
             'Chassis Fan2 (ISI F2)': 7552.0,
             'Chassis Fan3 (ISI F3)': 7387.0,
             'Class': 'storage',
             'Comps': ['Chassis',
                       'CPU',
                       'Motherboard',
                       'NVRam',
                       'FlashDrive',
                       'Disk_Controller',
                       'Disk_Expander',
                       'Power_Supplies'],
             'Config': '912-111-231',
             'DskCtl': 'LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)',
             'DskExp': 'VIT7156 (Vitesse 7156 Disk Expander)',
             'FlshDrv': 'None (No physical dongle supported) ((null))',
             'HWGen': 'MaunaLoa (MaunaLoa Hardware)',
             'IBType': 'ISI25208 (Isilon MT25208-based IB Card)',
             'IMB': 'Board Version 0x20f',
             'LCDver': 'NoriVFD (Noritake VFD)',
             'Mobo': 'SupMicX7DBU (SuperMicro X7DBU Motherboard)',
             'NVRam': 'MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)',
             'NetIF': 'em*4,ib*2 (4x Intel, 2x IB)',
             'PROC': 'Dual-proc, Quad-core',
             'Power Supplies OK': None,
             'Power Supply 1 Fan': 5504.0,
             'Power Supply 2 Fan': 5792.0,
             'Product': 'IQ 32000x-ssd',
             'PwrSupl': ['PS1 (type=Emerson, fw=v.01.00.00)',
                         'PS2 (type=Emerson, fw=v.01.00.00)'],
             'RAM': '17150812160 Bytes',
             'SerNo': 'S123456789P',
             'Series': 'x_series',
             'Temp Chassis 2 (ISI T2)': 22.0,
             'Temp Front Panel': 17.0,
             'Temp System': 25.0,
             'Temp Until CPU Throttle (CPU 0)': 46.0,
             'Temp Until CPU Throttle (CPU 1)': 42.0},
 'visi-92': {'CPU': 'GenuineIntel (2.33GHz, stepping 0x0001067a)',
             'CPU Operation (raw 0x882E0000)': 'Normal',
             'CPU Speed Limit': '100.00%',
             'ChasCnt': '1 (Single-Chassis System)',
             'Chassis': 'ISI36 (Isilon (CIDesigns) 36-Bay Chassis)',
             'Chassis Fan1 (ISI F1)': 7268.0,
             'Chassis Fan2 (ISI F2)': 7307.0,
             'Chassis Fan3 (ISI F3)': 7190.0,
             'Class': 'storage',
             'Comps': ['Chassis',
                       'CPU',
                       'Motherboard',
                       'NVRam',
                       'FlashDrive',
                       'Disk_Controller',
                       'Disk_Expander',
                       'Power_Supplies'],
             'Config': '912-111-231',
             'DskCtl': 'LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)',
             'DskExp': 'VIT7156 (Vitesse 7156 Disk Expander)',
             'FlshDrv': 'None (No physical dongle supported) ((null))',
             'HWGen': 'MaunaLoa (MaunaLoa Hardware)',
             'IBType': 'ISI25208 (Isilon MT25208-based IB Card)',
             'IMB': 'Board Version 0x20f',
             'LCDver': 'NoriVFD (Noritake VFD)',
             'Mobo': 'SupMicX7DBU (SuperMicro X7DBU Motherboard)',
             'NVRam': 'MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)',
             'NetIF': 'em*4,ib*2 (4x Intel, 2x IB)',
             'PROC': 'Dual-proc, Quad-core',
             'Power Supplies OK': None,
             'Power Supply 1 Fan': 5376.0,
             'Power Supply 2 Fan': 5696.0,
             'Product': 'IQ 32000x-ssd',
             'PwrSupl': ['PS1 (type=Emerson, fw=v.01.00.00)',
                         'PS2 (type=Emerson, fw=v.01.00.00)'],
             'RAM': '17150812160 Bytes',
             'SerNo': 'S123456785K',
             'Series': 'x_series',
             'Temp Chassis 2 (ISI T2)': 24.0,
             'Temp Front Panel': 17.2,
             'Temp System': 27.0,
             'Temp Until CPU Throttle (CPU 0)': 46.0,
             'Temp Until CPU Throttle (CPU 1)': 46.0},
 'visi-93': {'CPU': 'GenuineIntel (2.33GHz, stepping 0x0001067a)',
             'CPU Operation (raw 0x88250000)': 'Normal',
             'CPU Speed Limit': '100.00%',
             'ChasCnt': '1 (Single-Chassis System)',
             'Chassis': 'ISI36 (Isilon (CIDesigns) 36-Bay Chassis)',
             'Chassis Fan1 (ISI F1)': 7387.0,
             'Chassis Fan2 (ISI F2)': 7152.0,
             'Chassis Fan3 (ISI F3)': 7152.0,
             'Class': 'storage',
             'Comps': ['Chassis',
                       'CPU',
                       'Motherboard',
                       'NVRam',
                       'FlashDrive',
                       'Disk_Controller',
                       'Disk_Expander',
                       'Power_Supplies'],
             'Config': '912-111-231',
             'DskCtl': 'LSI3081E-HBA (LSI SAS3081E SAS Controller -- HBA) (8 ports)',
             'DskExp': 'VIT7156 (Vitesse 7156 Disk Expander)',
             'FlshDrv': 'None (No physical dongle supported) ((null))',
             'HWGen': 'MaunaLoa (MaunaLoa Hardware)',
             'IBType': 'ISI25208 (Isilon MT25208-based IB Card)',
             'IMB': 'Board Version 0x20f',
             'LCDver': 'NoriVFD (Noritake VFD)',
             'Mobo': 'SupMicX7DBU (SuperMicro X7DBU Motherboard)',
             'NVRam': 'MT25208 (Mellanox 25208 based Card) (492MB card) (size 515899392B)',
             'NetIF': 'em*4,ib*2 (4x Intel, 2x IB)',
             'PROC': 'Dual-proc, Quad-core',
             'Power Supplies OK': None,
             'Power Supply 1 Fan': 8512.0,
             'Power Supply 2 Fan': 8512.0,
             'Product': 'IQ 32000x-ssd',
             'PwrSupl': ['PS1 (type=Emerson, fw=v.03.05.00)',
                         'PS2 (type=Emerson, fw=v.03.05.00)'],
             'RAM': '17150812160 Bytes',
             'SerNo': 'S987654321P',
             'Series': 'x_series',
             'Temp Chassis 2 (ISI T2)': 25.0,
             'Temp Front Panel': 17.4,
             'Temp System': 28.0,
             'Temp Until CPU Throttle (CPU 0)': 37.0,
             'Temp Until CPU Throttle (CPU 1)': 38.0}}

Edit: Now handles multiple occurrences of a given 'key', by forming an array (e.g: PwrSupl).


来源: stackexchange

问:
Querying the best result in terms of sum of column's rows in Eloquent ORM laravel?
I have a table like this

Now first I am querying the results in term of same temperatur and zeit e.g.

```<code>(select * from table where temperatur= array..  AND zeit=array...).
</code>```

Now for example I get a result something like this:

one with temperatur and zeit= 85,30 and other one with 85,45..

Now according to the sum of columns of (aussehen,farbe,deformation,geruch,texture) I want to get the best result.

e.g the final sum of rows of  matching columns is( 14) and the other match is (17)  I want to get the best result which is 14..

How can I do that in laravel orm?

For the whole query I used this

```<code>orderBy( DB::raw('(aussehen) + (farbe)+(deformation)+(geruch)+(texture)'))->limit(1)->get();
</code>```

but know I want to compare results of sum..

I hope i have explained my question correctly..

答:
Try this:</p>

```<code>$result = DB::('table')
     ->select(DB::raw('*, (aussehen) + (farbe)+(deformation)+(geruch)+(texture) as sum'))
     ->where('temperature', '=', $temp) //variable passed to function
     ->where('zeit', '=', $zeit) // variable passed to function
     ->orderBy('sum', 'asc')
     ->first();
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a table like this

Now first I am querying the results in term of same temperatur and zeit e.g.

(select * from table where temperatur= array..  AND zeit=array...).

Now for example I get a result something like this:

one with temperatur and zeit= 85,30 and other one with 85,45..

Now according to the sum of columns of (aussehen,farbe,deformation,geruch,texture) I want to get the best result.

e.g the final sum of rows of  matching columns is( 14) and the other match is (17)  I want to get the best result which is 14..

How can I do that in laravel orm?

For the whole query I used this

orderBy( DB::raw('(aussehen) + (farbe)+(deformation)+(geruch)+(texture)'))->limit(1)->get();

but know I want to compare results of sum..

I hope i have explained my question correctly..

Body:
Try this:

$result = DB::('table')
     ->select(DB::raw('*, (aussehen) + (farbe)+(deformation)+(geruch)+(texture) as sum'))
     ->where('temperature', '=', $temp) //variable passed to function
     ->where('zeit', '=', $zeit) // variable passed to function
     ->orderBy('sum', 'asc')
     ->first();

ContentLicense: CC BY-SA 3.0


问:
Getting java.lang.ClassNotFoundException: SessionFactory when I try to deploy the war
I am trying to deploy war on TC server using STS. I am able to build the project without any dependency issues. But once I try to add the war to the server , I get the following error:

```<code>[2017-03-29 09:27:14,303] ERROR [ContextLoader]Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ApplConfigService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configManager': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'UserAuthentication': Injection of resource dependencies failed; nested exception is java.lang.NoClassDefFoundError: SessionFactory
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:311)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4729)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:586)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1750)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
</code>```

Troubleshooting steps I tried:

I made sure the war that was built had all the necessary jars under WEB_INF/lib

Tried adding the jars to buildpath

Made sure maven dependencies are added under Preferences->Deployment Assembly

Cleaned the server several times

Forced maven to download all the jars again

Did Maven install from command line to make sure the wars are building properly

Tried deploying the war manually into tomcat/STS and starting the server on command line. It starts without this error but gives 404 for the application URL.

Tried STS and Eclipse

For some reason it is not able to find the Hibernate jars from the server. I have tried most of the solutions I came across for this error on Stack overflow but it doesn't go away.

Any insights on this will be greatly appreciated!

答:
I don't have enough points to comment, this would be better as a comment.  But for posterity sake: Many people are not aware that a war file and an ear file are simply zipped up content with specific files in specific places.  To look at the file, you can rename the extension to ".zip" and then browse the files inside.

I know you already answered your own question, but others might find this useful. :)

Body:
I am trying to deploy war on TC server using STS. I am able to build the project without any dependency issues. But once I try to add the war to the server , I get the following error:

[2017-03-29 09:27:14,303] ERROR [ContextLoader]Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ApplConfigService': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configManager': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'UserAuthentication': Injection of resource dependencies failed; nested exception is java.lang.NoClassDefFoundError: SessionFactory
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:311)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4729)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:586)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1750)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Troubleshooting steps I tried:

I made sure the war that was built had all the necessary jars under WEB_INF/lib

Tried adding the jars to buildpath

Made sure maven dependencies are added under Preferences->Deployment Assembly

Cleaned the server several times

Forced maven to download all the jars again

Did Maven install from command line to make sure the wars are building properly

Tried deploying the war manually into tomcat/STS and starting the server on command line. It starts without this error but gives 404 for the application URL.

Tried STS and Eclipse

For some reason it is not able to find the Hibernate jars from the server. I have tried most of the solutions I came across for this error on Stack overflow but it doesn't go away.

Any insights on this will be greatly appreciated!


问:
PHP Cloud Datastore and Cloud Dataflow
I designed to keep raw data from IoT devices to Cloud DataStore via GAE Flex (PHP). I also want to bring those data to BigQuery via Cloud DataFlow. However, I cannot find the standard or official documents which express the ways to read and dump data among DataStore and DataFlow services.  </p>

答:
The easiest way to achieve this is by using BigQuery's ability to load Cloud Datastore backups. Essentially just schedule a regular backup into a GCS bucket, then load the backup from GCS into BigQuery. [documentation].

If you want to use Dataflow, you can use the DatastoreIO source in Java or Python (sorry, no PHP here). [documentation]

Read results from a query into a PCollection:

```<code>Pipeline p = Pipeline.create(options);
PCollection<Entity> entities = p.apply(
   DatastoreIO.v1().read()
       .withProjectId(projectId)
       .withQuery(myQueryObject));
</code>```

Then write this PCollection to wherever you want the data.

Title: PHP Cloud Datastore and Cloud Dataflow

Body:
The easiest way to achieve this is by using BigQuery's ability to load Cloud Datastore backups. Essentially just schedule a regular backup into a GCS bucket, then load the backup from GCS into BigQuery. [documentation].

If you want to use Dataflow, you can use the DatastoreIO source in Java or Python (sorry, no PHP here). [documentation]

Read results from a query into a PCollection:

Pipeline p = Pipeline.create(options);
PCollection<Entity> entities = p.apply(
   DatastoreIO.v1().read()
       .withProjectId(projectId)
       .withQuery(myQueryObject));

Then write this PCollection to wherever you want the data.


问:
Regex for ranges of values in comma-separated list
I want to write a regex that match a list of numeric values, given in a comma-separated list, ranges allowed. Empty is not allowed.

Something like: 1-10,20-56,8,7

So far I have (([0-9]+)|([0-9]+-[0-9]+),)*[0-9]+. This does most of the job, except it misses the case of one range only (eg: 1-10 would not validate).

The checking for each range can be omitted (eg: 20-10 can be allowed as a valid range).

Any help would be appreciated.

ContentLicense: CC BY-SA 2.5

Body:
You can use the regex;

^([0-9]+(-[0-9]+)?)(,([0-9]+(-[0-9]+)?))*$

Regex in action


问:
Call function for paired arguments
Here is simple script to generate greeting messages:

```<code>def greeting(event, person):
    print("Happy " + event + ", dear " + person + ".")

event = "Birthday"
person = "Emily"
greeting(event, person) # Happy Birtday, dear Emily.

event = "New Year"
person = "Mark"
greeting(event, person) # Happy New Year, dear Mark.
</code>```

Is there way to get the same result, but call the greeting function only once?

答:
You can put this in a loop to handle a list of names and events.  I'd recommend keeping the inner function the same, and firing a sequence of data at it from outside.  Depending on your application, mileage may vary.</p>

```<code>def greeting(event, person):
    print("Happy " + event + ", dear " + person + ".")

event_list = [("Birthday", "Emily"),
              ("New Year", "Mark")]
for event, person in event_list:
    greeting(event, person)
</code>```

Title: Call function for paired arguments

Body:
Here is simple script to generate greeting messages:

def greeting(event, person):
    print("Happy " + event + ", dear " + person + ".")

event = "Birthday"
person = "Emily"
greeting(event, person) # Happy Birtday, dear Emily.

event = "New Year"
person = "Mark"
greeting(event, person) # Happy New Year, dear Mark.

Is there way to get the same result, but call the greeting function only once?

Body:
You can put this in a loop to handle a list of names and events.  I'd recommend keeping the inner function the same, and firing a sequence of data at it from outside.  Depending on your application, mileage may vary.

def greeting(event, person):
    print("Happy " + event + ", dear " + person + ".")

event_list = [("Birthday", "Emily"),
              ("New Year", "Mark")]
for event, person in event_list:
    greeting(event, person)


问:
Firebase childAdded observer not fired when child pushed from firebase admin (nodejs)
So I've been struggling to get this to work. Essentially I'm building a chat app and relying on an childAdded observer to check for new messages. In my iOS App I'm using the following:

```<code>//Get ref to users chat node
let messagesRef = dbRef.child("chats").child(self.userId)
//Only get most recent message

let messageQuery = messagesRef.queryOrdered(byChild: "messageTimeStamp").queryLimited(toLast: 1)

// Listen for new messages (last 1) being written to the Firebase DB
messageQuery.observe(.childAdded, with: { (snapshot) -> Void in...
</code>```

This works fine when the user adds a message to /chat/uid. But when I add a child node from firebase admin (node js) the observer is never fired.

This is how I'm adding a message from the server side:

```<code>ref.child('chats/'+ uid).push(message);
</code>```

The message is properly added to the tree, but no observer is ever fired.

Try as I might, and after a dozen tweaks that produced no difference, I'm sure I'm missing something simple. Help!

答:
Solved it just after posting the question...typical! Adding .set seems to make the observer work, even though the documentation states it's identical.

This works:

```<code>ref.child('chats/'+ uid).push().set(message);
</code>```

Body:
So I've been struggling to get this to work. Essentially I'm building a chat app and relying on an childAdded observer to check for new messages. In my iOS App I'm using the following:

//Get ref to users chat node
let messagesRef = dbRef.child("chats").child(self.userId)
//Only get most recent message

let messageQuery = messagesRef.queryOrdered(byChild: "messageTimeStamp").queryLimited(toLast: 1)

// Listen for new messages (last 1) being written to the Firebase DB
messageQuery.observe(.childAdded, with: { (snapshot) -> Void in...

This works fine when the user adds a message to /chat/uid. But when I add a child node from firebase admin (node js) the observer is never fired.

This is how I'm adding a message from the server side:

ref.child('chats/'+ uid).push(message);

The message is properly added to the tree, but no observer is ever fired.

Try as I might, and after a dozen tweaks that produced no difference, I'm sure I'm missing something simple. Help!

Body:
Solved it just after posting the question...typical! Adding .set seems to make the observer work, even though the documentation states it's identical.

This works:

ref.child('chats/'+ uid).push().set(message);


问:
PHP OOP- inject DB class to a construct method of another class
I have a Database class for connecting to DB.

```<code> <?php

require_once('config.php');

class Database {

   function __construct(){
     $this->connect();
   }

   public function connect(){
     $this->connection = mysqli_connect(SERVER, USERNAME, PASSWORD, DATABASE);
   }

}

 ?>
</code>```

And a main class where I need to use the DB connection:

```<code>include 'includes/database.php';

class Main{

    var $mysqli;

    public function __construct(){
        $this->mysqli = new Database();
    }
</code>```

But this is not working, since I get an error for queries that are still in the main classes, I intend to move them to the DB class later. But now I am getting an error:

Fatal error: Uncaught Error: Call to undefined method
  Database::query() in /home/vagrant/Projects/MyProject/index.php
  on line 262

Queries are done in the Main class:

```<code>$result = $this->mysqli->query( "SELECT shops.*, shops.id AS shop,SUM(price)...
</code>```

答:
You are trying to call a query() method on the Database class. While that class contains a mysqli object in its $connection property, it does not expose the query() method of that mysqli object.

Given your current code, you could drill further into the object structure to call query() directly on the mysqli, but this is messy.

```<code>// Call the query() method directly on the connection
$result = $this->mysqli->connection->query( "SELECT shops.*, shops.id AS shop,SUM(price)...
</code>```

I don't like this approach because it requires that your classes know more about the inner workings of the Database class than they probably should. It couples them too tightly.

As an alternative, you could create a query() method in the Database class that wraps the necessary functionality of the mysqli object within it.

```<code>class Database {

   function __construct(){
     $this->connect();
   }

   public function connect(){
     $this->connection = mysqli_connect(SERVER, USERNAME, PASSWORD, DATABASE);
   }

   // Expose a query() method that calles the inner mysqli's query
   public function query($sql) {
     return $this->connection->query($sql);
   }
}
</code>```

This would allow you to pack in more functionality, such as querying and fetching all result rows in one method call:

```<code>class Database {
   //....

   // A more featured query() that returns the
   // rows as an array
   public function query($sql) {
     $result = $this->connection->query($sql);
     while ($row = $result->fetch_assoc()) {
        $rows[] = $row;
     }
     // Return an array of all the rows fetched from the query
     return $rows;
   }
}
</code>```

If you do it this way, you should be able to call $this->mysqli->query("...") as you originally attempted and either get back the result resource with the simple version, after which you must fetch in the code yourself, or get back an array of associative result rows in the more featured version.

Creating these kinds of database wrapper classes can get unwieldy rather quickly though.  Think carefully about what aspects of the mysqli object you want to expose to the other classes in your application. It's not a good idea to go down a path of wrapping every mysqli method in your Database class. At that point, the utility of the Database class is greatly reduced and you may as well just be passing in a mysqli object directly. If you are not actively adding functionality to mysqli, it makes less sense to create another class that wraps it.

A note about the var $mysqli;... This is an old deprecated class property syntax. The var keyword is a vestige from PHP4 and its use is discouraged nowadays. In fact, it has been removed from recent PHP versions.  Instead, you should declare it via the PHP5+ syntax:

```<code>// Declare as a public property
public $mysqli;

// Or better, as a private (or protected) property so it cannot
// be accessed outside the Main class' own methods
private $mysqli;
</code>```

In your question title, you mentioned injection. Your class doesn't do that right now, but it would be a good idea to instantiate a Database ahead of time and inject one into the class constructors that need it.

```<code>class Main{

    public $mysqli;

    // Pass a database as a constructor param
    public function __construct($database){
        $this->mysqli = $database;
    }
</code>```

Then instantiate it as:

```<code>$db = new Database();
// Pass the $db to the other classes
$main = new Main($db);
</code>```

Importantly, this will prevent you from opening up a separate database connection for each object you instantiate of Main and any other class you construct in the same way.  Doing that can quickly use up the server's available MySQL connections.

Body:
I have a Database class for connecting to DB.

 <?php

require_once('config.php');

class Database {

   function __construct(){
     $this->connect();
   }

   public function connect(){
     $this->connection = mysqli_connect(SERVER, USERNAME, PASSWORD, DATABASE);
   }

}

 ?>

And a main class where I need to use the DB connection:

include 'includes/database.php';

class Main{

    var $mysqli;

    public function __construct(){
        $this->mysqli = new Database();
    }

But this is not working, since I get an error for queries that are still in the main classes, I intend to move them to the DB class later. But now I am getting an error:

Fatal error: Uncaught Error: Call to undefined method
  Database::query() in /home/vagrant/Projects/MyProject/index.php
  on line 262

Queries are done in the Main class:

$result = $this->mysqli->query( "SELECT shops.*, shops.id AS shop,SUM(price)...

Body:
You are trying to call a query() method on the Database class. While that class contains a mysqli object in its $connection property, it does not expose the query() method of that mysqli object.

Given your current code, you could drill further into the object structure to call query() directly on the mysqli, but this is messy.

// Call the query() method directly on the connection
$result = $this->mysqli->connection->query( "SELECT shops.*, shops.id AS shop,SUM(price)...

I don't like this approach because it requires that your classes know more about the inner workings of the Database class than they probably should. It couples them too tightly.

As an alternative, you could create a query() method in the Database class that wraps the necessary functionality of the mysqli object within it.

class Database {

   function __construct(){
     $this->connect();
   }

   public function connect(){
     $this->connection = mysqli_connect(SERVER, USERNAME, PASSWORD, DATABASE);
   }

   // Expose a query() method that calles the inner mysqli's query
   public function query($sql) {
     return $this->connection->query($sql);
   }
}

This would allow you to pack in more functionality, such as querying and fetching all result rows in one method call:

class Database {
   //....

   // A more featured query() that returns the
   // rows as an array
   public function query($sql) {
     $result = $this->connection->query($sql);
     while ($row = $result->fetch_assoc()) {
        $rows[] = $row;
     }
     // Return an array of all the rows fetched from the query
     return $rows;
   }
}

If you do it this way, you should be able to call $this->mysqli->query("...") as you originally attempted and either get back the result resource with the simple version, after which you must fetch in the code yourself, or get back an array of associative result rows in the more featured version.

Creating these kinds of database wrapper classes can get unwieldy rather quickly though.  Think carefully about what aspects of the mysqli object you want to expose to the other classes in your application. It's not a good idea to go down a path of wrapping every mysqli method in your Database class. At that point, the utility of the Database class is greatly reduced and you may as well just be passing in a mysqli object directly. If you are not actively adding functionality to mysqli, it makes less sense to create another class that wraps it.

A note about the var $mysqli;... This is an old deprecated class property syntax. The var keyword is a vestige from PHP4 and its use is discouraged nowadays. In fact, it has been removed from recent PHP versions.  Instead, you should declare it via the PHP5+ syntax:

// Declare as a public property
public $mysqli;

// Or better, as a private (or protected) property so it cannot
// be accessed outside the Main class' own methods
private $mysqli;

In your question title, you mentioned injection. Your class doesn't do that right now, but it would be a good idea to instantiate a Database ahead of time and inject one into the class constructors that need it.

class Main{

    public $mysqli;

    // Pass a database as a constructor param
    public function __construct($database){
        $this->mysqli = $database;
    }

Then instantiate it as:

$db = new Database();
// Pass the $db to the other classes
$main = new Main($db);

Importantly, this will prevent you from opening up a separate database connection for each object you instantiate of Main and any other class you construct in the same way.  Doing that can quickly use up the server's available MySQL connections.


问:
Python 2.7 : store the variable value permanently even when I run the session next time
Scenario: python code which checks the number of visitors entered through a gate.
depending on that number I build the next job.

EDIT 1 :

#

file1 :(
First Run
this file counts the number of visitors that are arriving default is 3 in my case. Now i execute the file and I found that visitors arrived are 4 . Now and export the same to file2 and print the visitor count as 4 at the same time the visitors value is changed to 4 now in file1.

Now the second run:

Now in file1 the visitors value is 4 and it is checking if visitors > 4 , now if the count is 4 then i export the same to file2 if count is 5 now then i export the same to file2 and retain the value as 5 **count of visitors completely depends on the URL) ####

```<code>datasource = "www.PPrestraunt.com/personsentered"
data = len(datasource) #gives me the live value of the number of persons entered
if(visitors > 3):
   bottles = data
   visitors = bottles
   print bottles
else:
   visitors = 3
</code>```

this above code is imported to a another file which has the working

file2:

```<code>from file1 import visitors
number_of_bottles = visitors
print number_of_bottles
</code>```

I have setup the same in jenkins job so it builds every 5 mins.
In the above code the value of visitors is not changing every time I am running the code value remains 3 even though the number is increased to 4.

expected case: If value is more than 3 value should be retained in next session too and the if condition should now check for the new value ex: (if(visitors > 4)

any help is appreciated.

答:
This would be a great scenario for pickling. You can pickle data (in your case a counter) and store this data, then retrieve it at a later point in time:

```<code>import pickle

def your_code(counter):
    # Replace this with your code and use the counter variable.
    # Every time you execute the code it will increase
    # e.g. 3, 4, 5, 6 ....
    print(counter)

try:
    counter = pickle.load(open('counter.pckl', 'rb'))
    counter += 1
    pickle.dump(counter, open('counter.pckl', 'wb'))
    # Now execute your code with the new counter:
    your_code(counter)

except:
    counter = 3
    pickle.dump(counter, open('counter.pckl', 'wb'))
    # Execute your code for the first time. This will only happen once.
    your_code(counter)
</code>```

The first time you execute this code, the counter will be initialized to 3. You can then call your existing code as a function and use this counter. Whenever you run the script, the counter will increase and your code will use the new version of counter: e.g. 3, 4, 5, 6.

Body:
Scenario: python code which checks the number of visitors entered through a gate.
depending on that number I build the next job.

EDIT 1 :

#

file1 :(
First Run
this file counts the number of visitors that are arriving default is 3 in my case. Now i execute the file and I found that visitors arrived are 4 . Now and export the same to file2 and print the visitor count as 4 at the same time the visitors value is changed to 4 now in file1.

Now the second run:

Now in file1 the visitors value is 4 and it is checking if visitors > 4 , now if the count is 4 then i export the same to file2 if count is 5 now then i export the same to file2 and retain the value as 5 **count of visitors completely depends on the URL) ####

datasource = "www.PPrestraunt.com/personsentered"
data = len(datasource) #gives me the live value of the number of persons entered
if(visitors > 3):
   bottles = data
   visitors = bottles
   print bottles
else:
   visitors = 3

this above code is imported to a another file which has the working

file2:

from file1 import visitors
number_of_bottles = visitors
print number_of_bottles

I have setup the same in jenkins job so it builds every 5 mins.
In the above code the value of visitors is not changing every time I am running the code value remains 3 even though the number is increased to 4.

expected case: If value is more than 3 value should be retained in next session too and the if condition should now check for the new value ex: (if(visitors > 4)

any help is appreciated.

Body:
This would be a great scenario for pickling. You can pickle data (in your case a counter) and store this data, then retrieve it at a later point in time:

import pickle

def your_code(counter):
    # Replace this with your code and use the counter variable.
    # Every time you execute the code it will increase
    # e.g. 3, 4, 5, 6 ....
    print(counter)

try:
    counter = pickle.load(open('counter.pckl', 'rb'))
    counter += 1
    pickle.dump(counter, open('counter.pckl', 'wb'))
    # Now execute your code with the new counter:
    your_code(counter)

except:
    counter = 3
    pickle.dump(counter, open('counter.pckl', 'wb'))
    # Execute your code for the first time. This will only happen once.
    your_code(counter)

The first time you execute this code, the counter will be initialized to 3. You can then call your existing code as a function and use this counter. Whenever you run the script, the counter will increase and your code will use the new version of counter: e.g. 3, 4, 5, 6.


问:
How to combine three lists of different size in order Python
I have three lists: signal, returns, and pct_list:

```<code>     signal= ['signal0', 'signal1', 'signal2']

     returns = ['retSCIENCE_MSFT','retLOVE_MSFT','retMUSIC_MSFT',
                 'retSCIENCE_YHOO', 'retLOVE_YHOO', 'retMUSIC_YHOO']

     pct_list = ['Pct_MSFT', 'Pct_YHOO']
</code>```

I tried using the zip function and it gave me the following result:

```<code>    ret_sig_list = list(zip(returns, signal, pct_list))
    ret_sig_list
</code>```

Output:

```<code>     [('retSCIENCE_MSFT', 'signal0', 'Pct_MSFT'),
      ('retLOVE_MSFT', 'signal1', 'Pct_YHOO')]
</code>```

What I'm trying to get is both MSFT and YHOO lined up with the corresponding signal and percent change like so:

```<code>ret_sig_list = [('retSCIENCE_MSFT', 'signal0', 'Pct_MSFT'),
               ('retLOVE_MSFT', 'signal1', 'Pct_MSFT'),
               ('retMUSIC_MSFT', 'signal2', 'Pct_MSFT'),
               ('retSCIENCE_YHOO', 'signal0', 'Pct_YHOO'),
               ('retLOVE_YHOO', 'signal1', 'Pct_YHOO'),
               ('retMUSIC_YHOO','signal2', 'Pct_YHOO')]
</code>```

I tried with list(zip(returns, signal, pct_list)), but it seems to default down to the lowest number of elements in the three lists, which is pct_list.

If anyone knows how I can tackle this problem, I'd be very greatful!
I'd like to use the ret_sig_list with a for-loop to perform a calculation on multiple stocks percent change goes up or down to give returns based on the associated words; science, love, music, etc.
I got the words from a Python package for Google Trends called Pytrends which I'd recommend, it's very cool!

答:
So I managed to almost find a solution, it's not ideal, but close. I say not ideal cause not including the specific words from the list of ["SCIENCE", "LOVE", "MUSIC"] but it's the only way to create an ordered zip list.

```<code>  stock_list = ['MSFT', 'YHOO']
  stock_list_v2 = []

     for stock in stock_list:
          for i in range(10):
           s = 'ret' + str(i) + '_' + stock

           stock_list_v2.append(s)
  stock_list_v2
</code>```

Output:

```<code>  ['ret0_MSFT',
  'ret1_MSFT',
  'ret2_MSFT',
  'ret3_MSFT',
  'ret4_MSFT',
  'ret5_MSFT',
  'ret6_MSFT',
  'ret7_MSFT',
  'ret8_MSFT',
  'ret9_MSFT',
  'ret0_YHOO',
  'ret1_YHOO',
  'ret2_YHOO',
  'ret3_YHOO',
  'ret4_YHOO',
  'ret5_YHOO',
  'ret6_YHOO',
  'ret7_YHOO',
  'ret8_YHOO',
  'ret9_YHOO']
</code>```

Next signals:

```<code>  sig = list(range(10))
  sig
  signal = ["signal{}".format(*sig) for sig in enumerate(sig)]
  signal
</code>```

Output:

```<code>  ['signal0',
   'signal1',
   'signal2',
   'signal3',
   'signal4',
   'signal5',
   'signal6',
   'signal7',
   'signal8',
   'signal9']
</code>```

Next, pct.

```<code>   stock_list = ['MSFT', 'YHOO']
   stock_list_v3 = []

   for stock in stock_list:
         for i in range(10):

         p = 'pct' + str(i) + '_' + stock
        stock_list_v3.append(p)
  stock_list_v3
</code>```

Output:

```<code>   ['pct0_MSFT',
    'pct1_MSFT',
    'pct2_MSFT',
    'pct3_MSFT',
    'pct4_MSFT',
    'pct5_MSFT',
    'pct6_MSFT',
    'pct7_MSFT',
    'pct8_MSFT',
    'pct9_MSFT',
    'pct0_YHOO',
    'pct1_YHOO',
    'pct2_YHOO',
    'pct3_YHOO',
    'pct4_YHOO',
    'pct5_YHOO',
    'pct6_YHOO',
    'pct7_YHOO',
    'pct8_YHOO',
    'pct9_YHOO']
</code>```

Now we import cycle from itertools like so.

```<code>     from itertools import cycle

     full_list = list(zip(stock_list_v2, cycle(signal), stock_list_v3))

     full_list
</code>```

Output:

```<code>     [('ret0_MSFT', 'signal0', 'pct0_MSFT'),
      ('ret1_MSFT', 'signal1', 'pct1_MSFT'),
      ('ret2_MSFT', 'signal2', 'pct2_MSFT'),
      ('ret3_MSFT', 'signal3', 'pct3_MSFT'),
      ('ret4_MSFT', 'signal4', 'pct4_MSFT'),
      ('ret5_MSFT', 'signal5', 'pct5_MSFT'),
      ('ret6_MSFT', 'signal6', 'pct6_MSFT'),
      ('ret7_MSFT', 'signal7', 'pct7_MSFT'),
      ('ret8_MSFT', 'signal8', 'pct8_MSFT'),
      ('ret9_MSFT', 'signal9', 'pct9_MSFT'),
      ('ret0_YHOO', 'signal0', 'pct0_YHOO'),
      ('ret1_YHOO', 'signal1', 'pct1_YHOO'),
      ('ret2_YHOO', 'signal2', 'pct2_YHOO'),
      ('ret3_YHOO', 'signal3', 'pct3_YHOO'),
      ('ret4_YHOO', 'signal4', 'pct4_YHOO'),
      ('ret5_YHOO', 'signal5', 'pct5_YHOO'),
      ('ret6_YHOO', 'signal6', 'pct6_YHOO'),
      ('ret7_YHOO', 'signal7', 'pct7_YHOO'),
      ('ret8_YHOO', 'signal8', 'pct8_YHOO'),
      ('ret9_YHOO', 'signal9', 'pct9_YHOO')]
</code>```

Hope that helps anyone who was curious about how to solve it :)
Thanks again to PrestonM for suggesting an algo, and Juapana for helping suggest using itertools cycle.

Body:
I have three lists: signal, returns, and pct_list:

     signal= ['signal0', 'signal1', 'signal2']

     returns = ['retSCIENCE_MSFT','retLOVE_MSFT','retMUSIC_MSFT',
                 'retSCIENCE_YHOO', 'retLOVE_YHOO', 'retMUSIC_YHOO']

     pct_list = ['Pct_MSFT', 'Pct_YHOO']

I tried using the zip function and it gave me the following result:

    ret_sig_list = list(zip(returns, signal, pct_list))
    ret_sig_list

Output:

     [('retSCIENCE_MSFT', 'signal0', 'Pct_MSFT'),
      ('retLOVE_MSFT', 'signal1', 'Pct_YHOO')]

What I'm trying to get is both MSFT and YHOO lined up with the corresponding signal and percent change like so:

ret_sig_list = [('retSCIENCE_MSFT', 'signal0', 'Pct_MSFT'),
               ('retLOVE_MSFT', 'signal1', 'Pct_MSFT'),
               ('retMUSIC_MSFT', 'signal2', 'Pct_MSFT'),
               ('retSCIENCE_YHOO', 'signal0', 'Pct_YHOO'),
               ('retLOVE_YHOO', 'signal1', 'Pct_YHOO'),
               ('retMUSIC_YHOO','signal2', 'Pct_YHOO')]

I tried with list(zip(returns, signal, pct_list)), but it seems to default down to the lowest number of elements in the three lists, which is pct_list.

If anyone knows how I can tackle this problem, I'd be very greatful!
I'd like to use the ret_sig_list with a for-loop to perform a calculation on multiple stocks percent change goes up or down to give returns based on the associated words; science, love, music, etc.
I got the words from a Python package for Google Trends called Pytrends which I'd recommend, it's very cool!

Body:
So I managed to almost find a solution, it's not ideal, but close. I say not ideal cause not including the specific words from the list of ["SCIENCE", "LOVE", "MUSIC"] but it's the only way to create an ordered zip list.

  stock_list = ['MSFT', 'YHOO']
  stock_list_v2 = []

     for stock in stock_list:
          for i in range(10):
           s = 'ret' + str(i) + '_' + stock

           stock_list_v2.append(s)
  stock_list_v2

Output:

  ['ret0_MSFT',
  'ret1_MSFT',
  'ret2_MSFT',
  'ret3_MSFT',
  'ret4_MSFT',
  'ret5_MSFT',
  'ret6_MSFT',
  'ret7_MSFT',
  'ret8_MSFT',
  'ret9_MSFT',
  'ret0_YHOO',
  'ret1_YHOO',
  'ret2_YHOO',
  'ret3_YHOO',
  'ret4_YHOO',
  'ret5_YHOO',
  'ret6_YHOO',
  'ret7_YHOO',
  'ret8_YHOO',
  'ret9_YHOO']

Next signals:

  sig = list(range(10))
  sig
  signal = ["signal{}".format(*sig) for sig in enumerate(sig)]
  signal

Output:

  ['signal0',
   'signal1',
   'signal2',
   'signal3',
   'signal4',
   'signal5',
   'signal6',
   'signal7',
   'signal8',
   'signal9']

Next, pct.

   stock_list = ['MSFT', 'YHOO']
   stock_list_v3 = []

   for stock in stock_list:
         for i in range(10):

         p = 'pct' + str(i) + '_' + stock
        stock_list_v3.append(p)
  stock_list_v3

Output:

   ['pct0_MSFT',
    'pct1_MSFT',
    'pct2_MSFT',
    'pct3_MSFT',
    'pct4_MSFT',
    'pct5_MSFT',
    'pct6_MSFT',
    'pct7_MSFT',
    'pct8_MSFT',
    'pct9_MSFT',
    'pct0_YHOO',
    'pct1_YHOO',
    'pct2_YHOO',
    'pct3_YHOO',
    'pct4_YHOO',
    'pct5_YHOO',
    'pct6_YHOO',
    'pct7_YHOO',
    'pct8_YHOO',
    'pct9_YHOO']

Now we import cycle from itertools like so.

     from itertools import cycle

     full_list = list(zip(stock_list_v2, cycle(signal), stock_list_v3))

     full_list

Output:

     [('ret0_MSFT', 'signal0', 'pct0_MSFT'),
      ('ret1_MSFT', 'signal1', 'pct1_MSFT'),
      ('ret2_MSFT', 'signal2', 'pct2_MSFT'),
      ('ret3_MSFT', 'signal3', 'pct3_MSFT'),
      ('ret4_MSFT', 'signal4', 'pct4_MSFT'),
      ('ret5_MSFT', 'signal5', 'pct5_MSFT'),
      ('ret6_MSFT', 'signal6', 'pct6_MSFT'),
      ('ret7_MSFT', 'signal7', 'pct7_MSFT'),
      ('ret8_MSFT', 'signal8', 'pct8_MSFT'),
      ('ret9_MSFT', 'signal9', 'pct9_MSFT'),
      ('ret0_YHOO', 'signal0', 'pct0_YHOO'),
      ('ret1_YHOO', 'signal1', 'pct1_YHOO'),
      ('ret2_YHOO', 'signal2', 'pct2_YHOO'),
      ('ret3_YHOO', 'signal3', 'pct3_YHOO'),
      ('ret4_YHOO', 'signal4', 'pct4_YHOO'),
      ('ret5_YHOO', 'signal5', 'pct5_YHOO'),
      ('ret6_YHOO', 'signal6', 'pct6_YHOO'),
      ('ret7_YHOO', 'signal7', 'pct7_YHOO'),
      ('ret8_YHOO', 'signal8', 'pct8_YHOO'),
      ('ret9_YHOO', 'signal9', 'pct9_YHOO')]

Hope that helps anyone who was curious about how to solve it :)
Thanks again to PrestonM for suggesting an algo, and Juapana for helping suggest using itertools cycle.


问:
Problem with NSRange
I'm having a problem with NSRange. Here is my code:

```<code>NSRange range = [[[NSHTTPCookie requestHeaderFieldsWithCookies:[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:cookie]]] objectForKey:@"Cookie"] rangeOfString:@"x"];
NSLog(@"%f", range.length);
if (range.length >= 1) {
    NSLog(@"Do Something");
} else {
    NSLog(@"AUTHING");
}
</code>```

Console output:

```<code>0.000000
Do something
</code>```

And then the second time I run through the code:

```<code>0.000000
AUTHING
</code>```

What the hell is going on? NSNotFound I think it was does not work and I'm not the only person finding this problem so using it is not a solution.

Thanks for any help.

Cheers

Edit: I tried using NSLog(@"%d", range.length) but it gives incorrect output the first time it runs through, the second time it runs through it is correct. I've tried using NSNotFound thinking that the strange output is due to it being NSNotFound but it didn't trigger

答:
If you want to see if the string was found using -[NSString rangeOfString:], you need to see if NSRange.location == NSNotFound:

```<code>if (range.location != NSNotFound) {
    // String was found
else {
    // String not found
}
</code>```

Title: Problem with NSRange

Body:
I'm having a problem with NSRange. Here is my code:

NSRange range = [[[NSHTTPCookie requestHeaderFieldsWithCookies:[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:cookie]]] objectForKey:@"Cookie"] rangeOfString:@"x"];
NSLog(@"%f", range.length);
if (range.length >= 1) {
    NSLog(@"Do Something");
} else {
    NSLog(@"AUTHING");
}

Console output:

0.000000
Do something

And then the second time I run through the code:

0.000000
AUTHING

What the hell is going on? NSNotFound I think it was does not work and I'm not the only person finding this problem so using it is not a solution.

Thanks for any help.

Cheers

Edit: I tried using NSLog(@"%d", range.length) but it gives incorrect output the first time it runs through, the second time it runs through it is correct. I've tried using NSNotFound thinking that the strange output is due to it being NSNotFound but it didn't trigger

Body:
If you want to see if the string was found using -[NSString rangeOfString:], you need to see if NSRange.location == NSNotFound:

if (range.location != NSNotFound) {
    // String was found
else {
    // String not found
}


答:
If you just want to the function to loop over the inputs, this should work:</p>

```<code>def greeting(messages):
    for event, person in messages:
        print("Happy " + event + ", dear " + person + ".")

greeting([('Birthday', 'Emily'), ('New Year', 'Mark')])
</code>```

Title: Call function for paired arguments

Body:
If you just want to the function to loop over the inputs, this should work:

def greeting(messages):
    for event, person in messages:
        print("Happy " + event + ", dear " + person + ".")

greeting([('Birthday', 'Emily'), ('New Year', 'Mark')])


问:
Wordpress Enqueuing Script returns 500 error
I am registering and enqueuing the script in my file functions.php
I got a white page and a console error 500

```<code>add_action( 'ninja_forms_insert_sub', 'ninja_forms_coregistration', 4 );
function ninja_forms_coregistration($sub_id){
    global $ninja_forms_processing;
    if( isset($ninja_forms_processing) && $ninja_forms_processing->data  AND  @$ninja_forms_processing->data['form']['sub_id'] ){
        $form = $ninja_forms_processing->data['form'] ;

        if($ninja_forms_processing->data['form_ID'] == 3){
            wp_enqueue_script('reworldmedia-ninja-forms-allianz-scripts', get_template_directory_uri().'/assets/javascripts/ninja-forms-allianz.js');
        }
        coregistration_send( $form, $ninja_forms_processing );
    }
}
</code>```

Here is my js file content:

```<code>jQuery(document).ready( function(){
    $(".ninja-forms-cont .ninja-forms-form").submit( function() {
        send_GA( "click-submit-form-allianz","submit","click sur allianz form" );
        return false;
    });
});
</code>```

答:
You need to register the script first, then enqueue it.

To do this, change:

```<code>wp_enqueue_script('reworldmedia-ninja-forms-allianz-scripts', get_template_directory_uri().'/assets/javascripts/ninja-forms-allianz.js');
</code>```

To the following:

```<code>wp_register_script('reworldmedia-ninja-forms-allianz-scripts',
get_template_directory_uri().'/assets/javascripts/ninja-forms-allianz.js');
wp_enqueue_style('reworldmedia-ninja-forms-allianz-scripts')
</code>```

Body:
I am registering and enqueuing the script in my file functions.php
I got a white page and a console error 500

add_action( 'ninja_forms_insert_sub', 'ninja_forms_coregistration', 4 );
function ninja_forms_coregistration($sub_id){
    global $ninja_forms_processing;
    if( isset($ninja_forms_processing) && $ninja_forms_processing->data  AND  @$ninja_forms_processing->data['form']['sub_id'] ){
        $form = $ninja_forms_processing->data['form'] ;

        if($ninja_forms_processing->data['form_ID'] == 3){
            wp_enqueue_script('reworldmedia-ninja-forms-allianz-scripts', get_template_directory_uri().'/assets/javascripts/ninja-forms-allianz.js');
        }
        coregistration_send( $form, $ninja_forms_processing );
    }
}

Here is my js file content:

jQuery(document).ready( function(){
    $(".ninja-forms-cont .ninja-forms-form").submit( function() {
        send_GA( "click-submit-form-allianz","submit","click sur allianz form" );
        return false;
    });
});

Body:
You need to register the script first, then enqueue it.

To do this, change:

wp_enqueue_script('reworldmedia-ninja-forms-allianz-scripts', get_template_directory_uri().'/assets/javascripts/ninja-forms-allianz.js');

To the following:

wp_register_script('reworldmedia-ninja-forms-allianz-scripts',
get_template_directory_uri().'/assets/javascripts/ninja-forms-allianz.js');
wp_enqueue_style('reworldmedia-ninja-forms-allianz-scripts')


问:
$http.get not sending data in the body of the request
Using angular v1.3.1 i got a singular the following problem trying to implement a facade for making http request to a REST + JSON interface in the backend of the web app.

I got something like this in the code:

```<code>findSomething(value: number): ng.IPromise<api.DrugIndication[]> {
  const getParams = { 'param' : 'value' };
  const config:ng.IRequestShortcutConfig = {
    headers: {
      "Content-Type" : "application/json"
    },
    data: getParams
  }
  return this.$http.get(url,config);
}
</code>```

And when the times comes to invoke it, i got an 400 Bad Request (btw: Great name for a band!) because the backend (made with Play for Scala) rejects the request inmediately. So making an inspection in the request i see that no data is being send in the body of the request/message.

So how i can send some data in the body of and HTTP Get request using angular "$http.get"?

Additional info: This doesn't happen if i the make request using the curl command from an ubuntu shell. So probably is an problem between Chrome and angular.js

答:
Using config.data will send the data in the request body, use

```<code>config.params = getParams
</code>```

This is from the documentation :

params – {Object.} – Map of strings or objects which will be serialized with the paramSerializer and appended as GET parameters

Body:
Using angular v1.3.1 i got a singular the following problem trying to implement a facade for making http request to a REST + JSON interface in the backend of the web app.

I got something like this in the code:

findSomething(value: number): ng.IPromise<api.DrugIndication[]> {
  const getParams = { 'param' : 'value' };
  const config:ng.IRequestShortcutConfig = {
    headers: {
      "Content-Type" : "application/json"
    },
    data: getParams
  }
  return this.$http.get(url,config);
}

And when the times comes to invoke it, i got an 400 Bad Request (btw: Great name for a band!) because the backend (made with Play for Scala) rejects the request inmediately. So making an inspection in the request i see that no data is being send in the body of the request/message.

So how i can send some data in the body of and HTTP Get request using angular "$http.get"?

Additional info: This doesn't happen if i the make request using the curl command from an ubuntu shell. So probably is an problem between Chrome and angular.js

Body:
Using config.data will send the data in the request body, use

config.params = getParams

This is from the documentation :

params – {Object.} – Map of strings or objects which will be serialized with the paramSerializer and appended as GET parameters


问:
What is the difference between gnustl_shared and gnustl_static in Android NDK library .a file?
I want to create android library using c++ stl.

my build tools are visual studio 2015, Visual GDB.

source code is

.cpp

```<code>#include <jni.h>
#include "AndroidProject2.h"
#include <vector>
void foo() { std::vector<int> aaa; aaa.push_back(1); }
</code>```

Android.mk

```<code># Generated by VisualGDB
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := AndroidProject2-shared
LOCAL_SRC_FILES := AndroidProject2.cpp
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := AndroidProject2-static
LOCAL_SRC_FILES :=  $(COMMON_SRC_FILES)
include $(BUILD_STATIC_LIBRARY)
</code>```

Application.mk

```<code>APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION :=4.9
</code>```

I succeed build, so, created lib files libAndroidProject2-static.a, libAndroidProject2-static.so

than, I try to change APP_STL option in Application.mk

```<code>APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_shared
NDK_TOOLCHAIN_VERSION :=4.9
</code>```

surely, succeed build. so, created lib files libAndroidProject2-shared.a, libAndroidProject2-shared.so

than, I Compare it and previous build outputs.

I Found the difference about .so file. gnustl_static option's .so file is more bigger than gnustl_shared option's it.
but .a is same.

why?
I used nm, readelf but can't find difference.
what is diff???

答:
There are two questions here:

Why does using gnustl_static make larger shared libraries than gnustl_shared?

When you use a static library you're including code from that library directly into your shared library, so your library grows. When you use a shared library you load the code that would have been included from the other shared library instead of including it. The size you need to compare is libAndroidProject2-static.so + libgnustl_shared.so, since both must be present at runtime.

Why didn't using gnustl_static make a larger static library?

Static libraries (libAndroidProject2-static.a, in this case) aren't linked; they're just archives of the compiled sources. libgnustl_static.a doesn't get included until you actually link libAndroidProject-static.a into something, at which point you'll also need to link libgnustl_static.a.

You'd see the size difference when you linked libAndroidProject2-static.a (and libgnustl_static.a) into a shared library or exeuctable.

Body:
I want to create android library using c++ stl.

my build tools are visual studio 2015, Visual GDB.

source code is

.cpp

#include <jni.h>
#include "AndroidProject2.h"
#include <vector>
void foo() { std::vector<int> aaa; aaa.push_back(1); }

Android.mk

# Generated by VisualGDB
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := AndroidProject2-shared
LOCAL_SRC_FILES := AndroidProject2.cpp
COMMON_SRC_FILES := $(LOCAL_SRC_FILES)
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := AndroidProject2-static
LOCAL_SRC_FILES :=  $(COMMON_SRC_FILES)
include $(BUILD_STATIC_LIBRARY)

Application.mk

APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_static
NDK_TOOLCHAIN_VERSION :=4.9

I succeed build, so, created lib files libAndroidProject2-static.a, libAndroidProject2-static.so

than, I try to change APP_STL option in Application.mk

APP_MODULES := AndroidProject2-static AndroidProject2-shared
APP_ABI := all
APP_STL := gnustl_shared
NDK_TOOLCHAIN_VERSION :=4.9

surely, succeed build. so, created lib files libAndroidProject2-shared.a, libAndroidProject2-shared.so

than, I Compare it and previous build outputs.

I Found the difference about .so file. gnustl_static option's .so file is more bigger than gnustl_shared option's it.
but .a is same.

why?
I used nm, readelf but can't find difference.
what is diff???