Creating Diagonals in SAS - sas

I am trying to convert my columns to diagonals using SAS.
For example
D C1 C2 C3 C4 C5
J 11 00 14 15 20
F 00 13 16 00 30
M 00 00 18 19 00
A 00 00 00 98 50
S 00 00 00 00 41
Want this converted to
D N1 N2 N3 N4 N5
J 11 00 14 15 20
F 13 16 00 30
M 18 19 00
A 98 50
M 41
Can anyone tell or help me with this?

Update base on new info: This just uses an array to shift the values starting from the diagonal to the left. Not dependent of on values in the lower triangle.
data havethis;
infile cards firstobs=2;
input D:$1. C1-C5;
cards;
D C1 C2 C3 C4 C5
J 11 00 14 15 20
F 00 13 16 00 30
M 00 00 18 19 00
A 00 00 00 98 50
S 00 00 00 00 41
;;;;
run;
data want;
set havethis;
array c[*] c:;
array N[&sysnobs];
j = 0;
do i = _n_ to dim(c);
j + 1;
n[j] = c[i];
end;
drop j i;
run;
This method use two transposes (flip/flop), it assumes only zeros are on the off diagonal (better if they were missing) and missing is what you get as result. I like this method because you don't have to know anything, like how many.
data havethis;
input D:$1. C1 C2 C3;
format c: z2.;
cards;
J 11 12 14
M 00 13 15
A 00 00 16
;;;;
run;
proc transpose data=havethis out=wantthis(drop=_name_ where=(col1 ne 0));
by D notsorted;
run;
proc transpose data=wantthis out=whatthismore(drop=_name_) prefix=N;
by d notsorted;
run;

Related

Problem in memory allocation of char variable in C++, through visual studio debbuger

char is a type that have one byte in C++, in a way that we can use it as signed or unsigned, changing the values it can allocate. I'm new using debugger in Visual Studio and also in reading about memory. I'm using the following code:
int main() {
signed char a = 170;
signed char* b = &a;
}
the range of a variable should be -128 to 127, the value of the variable is converted and -86 is settled, but when I get the value of the b variable, which is the memory alocation, to see what is there I get:
0x0019F99B aa cc cc cc cc 6d f3 ea 54 c4 f9 19 00 13 1f a0 00 01 00 00 00 60 78 76 00 d0 b5 76 00 01 00 00 00 60 78 76 00 d0 b5 76 00 20 fa 19 00 67 1d a0 00 e9 f0 ea 54 23 10 a0 00 23 10 a0 00 00 60 ªÌÌÌÌmóêTÄù.... .....`xv.еv.....`xv.еv. ú..g. .éðêT#. .#. ..
but aa in hexadecimal evaluates to 170. What happened?
The 170 literal is an int represented by 0x000000AA.
When you convert that into a single byte signed char, it simply truncates the bytes, so you wind up with 0xAA, which happens to be -86 in twos-complement notation.

Splitting of frame in different parts in bigquery

i've got a string frame looking like this in google bigquery:
S,0,2B3,8, C2 B3 00 00 00 00 03 DE
S,0,3FA,6, 00 E0 04 A5 00 0B
S,0,440,8, 80 40 4E A5 00 47 00 64
S,0,450,8, 89 50 01 12 01 19 01 B3
S,0,4B0,8, 80 B0 4E A5 00 43 00 64
my aim is to extract the 8 bytes at the end (eg 80 40 4E A5 00 47 00 64
). possible only the ones beginning with 83 and 84.
i didnt get it to work with neither split, trim, contains nor regexp_extract.
i'd be quite happy if anyone could help me.
regards
/edit
Thank you both very much for your solutions! this helped quite a lot.
#standardSQL
SELECT
*
FROM (
SELECT
timestamp,
REGEXP_EXTRACT(CAN_Frame, r', ([^,]+)$') AS bytes_string,
FROM_HEX(REPLACE(REGEXP_EXTRACT(CAN_Frame, r', ([^,]+)$'), ' ', '')) AS bytes
FROM `data.source`
)
WHERE SUBSTR(bytes, 1, 1) IN (b'\x83', b'\x84')
ORDER BY timestamp DESC
LIMIT 8000
gives me
Row timestamp bytes_string bytes
1 2017-09-29 14:31:02 UTC 84 10 00 25 00 21 00 4F hBAAJQAhAE8=
2 2017-09-29 14:30:42 UTC 83 80 00 01 00 03 00 0D g4AAAQADAA0=
3 2017-09-29 14:30:40 UTC 84 B2 00 27 00 08 00 03 hLIAJwAIAAM=
#standardSQL
SELECT
timestamp,
TRIM(SPLIT(CAN_Frame)[OFFSET(4)]) AS bytes
FROM
`data.source`
WHERE
LENGTH(CAN_Frame) > 1 and
SUBSTR(TRIM(SPLIT(CAN_Frame)[OFFSET(4)]),1,2) IN ('83', '84')
ORDER BY
timestamp DESC
LIMIT
8000
gives me
Row timestamp bytes
1 2017-09-29 14:31:02 UTC 84 10 00 25 00 21 00 4F
2 2017-09-29 14:30:42 UTC 83 80 00 01 00 03 00 0D
3 2017-09-29 14:30:40 UTC 84 B2 00 27 00 08 00 03
is there a possibility to get only the sixth and seventh byte from the bytes_string beginning with 83, to get 4th and 5th byte from the bytes_string beginning with 84 and to geht the 8th byte from string 83 and the 3rd byte from string 84 for further calculations?
best regards
Below is for BigQuery StandardSQL
#standardSQL
WITH `yourTable` AS (
SELECT 'S,0,2B3,8, C2 B3 00 00 00 00 03 DE' AS frame UNION ALL
SELECT 'S,0,3FA,6, 00 E0 04 A5 00 0B' UNION ALL
SELECT 'S,0,440,8, 80 40 4E A5 00 47 00 64' UNION ALL
SELECT 'S,0,450,8, 89 50 01 12 01 19 01 B3' UNION ALL
SELECT 'S,0,4B0,8, 80 B0 4E A5 00 43 00 64'
)
SELECT frame, TRIM(SPLIT(frame)[OFFSET(4)]) AS bytes
FROM `yourTable`
WHERE SUBSTR(TRIM(SPLIT(frame)[OFFSET(4)]), 1, 2) IN ('80', 'C2')
Here is an example that should help. It produces two columns with different interpretations of the bytes: one (bytes_string) is just the end of the strings that you showed, whereas the other (bytes) is the bytes string converted to an actual BYTES type. In the BigQuery UI, make sure to deselect "Use Legacy SQL" under "Show Options" or include the #standardSQL directive:
#standardSQL
WITH Frames AS (
SELECT 'S,0,2B3,8, C2 B3 00 00 00 00 03 DE' AS frame UNION ALL
SELECT 'S,0,3FA,6, 00 E0 04 A5 00 0B' UNION ALL
SELECT 'S,0,440,8, 80 40 4E A5 00 47 00 64' UNION ALL
SELECT 'S,0,450,8, 89 50 01 12 01 19 01 B3' UNION ALL
SELECT 'S,0,4B0,8, 80 B0 4E A5 00 43 00 64'
)
SELECT
frame,
REGEXP_EXTRACT(frame, r', ([^,]+)$') AS bytes_string,
FROM_HEX(REPLACE(REGEXP_EXTRACT(frame, r', ([^,]+)$'), ' ', '')) AS bytes
FROM Frames;
Here is another example that demonstrates filtering on the bytes column to include only values starting with \x83 or \x84 (this will return an empty result set for the sample data you provided):
#standardSQL
WITH Frames AS (
SELECT 'S,0,2B3,8, C2 B3 00 00 00 00 03 DE' AS frame UNION ALL
SELECT 'S,0,3FA,6, 00 E0 04 A5 00 0B' UNION ALL
SELECT 'S,0,440,8, 80 40 4E A5 00 47 00 64' UNION ALL
SELECT 'S,0,450,8, 89 50 01 12 01 19 01 B3' UNION ALL
SELECT 'S,0,4B0,8, 80 B0 4E A5 00 43 00 64'
)
SELECT
*
FROM (
SELECT
frame,
REGEXP_EXTRACT(frame, r', ([^,]+)$') AS bytes_string,
FROM_HEX(REPLACE(REGEXP_EXTRACT(frame, r', ([^,]+)$'), ' ', '')) AS bytes
FROM Frames
)
WHERE SUBSTR(bytes, 1, 1) IN (b'\x83', b'\x84');

Memory leaks in boost asio

I have client/server app. Interaction implemented via Boost.Asio.
I created unit test to check long running transmission of data.
During the test memory leak detected.
Task Manager shows me that memory usage constantly grows - up to 35MB per 10min. Report produced at the end of test contains this:
Result StandardError: Detected memory leaks!
Dumping objects ->
{14522} normal block at 0x00E8ADC0, 16 bytes long.
Data: < _M} Y > B0 5F 4D 7D F9 59 F2 02 F4 E9 E6 00 CC CC CC CC
{14012} normal block at 0x00E8B280, 16 bytes long.
Data: < v > C0 76 A4 00 94 01 00 00 98 01 00 00 F0 D2 E3 00
{14011} normal block at 0x00E74B38, 12 bytes long.
Data: < > 00 00 00 00 9C 01 00 00 98 01 00 00
{14007} normal block at 0x00E745F8, 8 bytes long.
Data: < L > E0 4C E5 00 00 00 00 00
{14006} normal block at 0x00E54CB8, 60 bytes long.
Data: < v 4 > E4 76 A4 00 D0 D3 B0 00 00 00 00 00 34 80 E3 00
{13724} normal block at 0x00E710F8, 385 bytes long.
Data: < > 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
{13722} normal block at 0x00E85C58, 28 bytes long.
Data: < F _ _ > F2 B6 46 00 B4 5F E3 00 A0 5F E3 00 BC 96 E7 00
{13720} normal block at 0x00E6F9B8, 80 bytes long.
Data: <wxF > 77 78 46 00 FC FF FF FF 00 00 00 00 CC CC CC CC
{13700} normal block at 0x00E6DFD0, 88 bytes long.
Data: < > C8 A4 A4 00 01 00 00 00 01 00 00 00 00 00 00 00
…
Data: <` X L > 60 8E E0 00 58 17 E2 00 CD 4C F7 EA
{153} normal block at 0x00DF0070, 12 bytes long.
Data: <` kf > 60 8D E0 00 98 00 E2 00 15 6B 66 0E
{151} normal block at 0x00DF0038, 12 bytes long.
Data: < .g> 20 86 E0 00 E0 FC E1 00 9D B7 2E 67
{149} normal block at 0x00DF0658, 12 bytes long.
Data: < G > A0 89 E0 00 00 00 00 00 47 01 D5 11
{147} normal block at 0x00DF0268, 12 bytes long.
Data: <` > 60 84 E0 00 A8 F5 E1 00 ED 8C AA BA
{145} normal block at 0x00DF0230, 12 bytes long.
Data: < ' " > 20 84 E0 00 00 11 E2 00 27 B0 22 00
{143} normal block at 0x00DF0690, 12 bytes long.
Data: <` P KnOQ> 60 88 E0 00 50 04 E2 00 4B 6E 4F 51
{141} normal block at 0x00DF0540, 12 bytes long.
Data: <` > 7> 60 82 E0 00 00 0A E2 00 3E 0D 9E 37
{139} normal block at 0x00DF0620, 12 bytes long.
Data: <Pq 1 > 50 71 DF 00 00 00 00 00 E5 DD 31 B5
{137} normal block at 0x00DF0700, 12 bytes long.
Data: < q # #> 10 71 DF 00 40 FA E1 00 14 8B 0D 23
{134} normal block at 0x00DF5CE0, 96 bytes long.
Data: <h BV BV > 68 19 E0 00 D0 42 56 00 E0 42 56 00 88 00 00 00
{133} normal block at 0x00DF0188, 8 bytes long.
Data: < \ > A0 5C DF 00 00 00 00 00
{132} normal block at 0x00DF5CA0, 16 bytes long.
Data: < > 88 01 DF 00 D8 AA DF 00 20 AC DF 00 20 AC DF 00
Object dump complete.
I tried to put breakpoint to mentioned memory allocations via boost's --detect_memory_leaks="allocation number" and setting in Watch window at Debug mode _crtBreakAlloc = 1000. It does not work. Maybe because leaks occur not in my code, but in boost/OpenSSL code?
I can't figure out where leaks occur. What can I do?
Windows 8, Visual Studio 2015, boost 1.60, OpenSSL 1.0.2g
Have a look at this post to see some suggested tips for dealing with memory leaks under windows. Have a scroll down, don't just look at the first answer. In particular it may be worth considering the DEBUG_NEW macro-based solution discussed by the second answer. Given that boost asio is largely header-only, this should help you even if the offending allocations come from the boost library.
Part 1: Report from Visual Studio about memory leaks
I'm using Boost.Asio to communicate with the server over TLS, i.e. Boost.Asio uses OpenSSL.
Seems that OpenSSL initializes itself and do not cleans memory before the end of the app (because app closes and memory will be released anyway).
This is not big chunk of memory (I do not know how to measure it).
As result Visual Studio treated that memory as leak. But it is not.
(This is my assumption, maybe real reason for such report is smth else. But I do not see any other possible reasons. )
Part 2:
In the question above I asked about memory leak for tens of Mb. This is my bad code that leads to huge memory buffer )).
Huge memory consumption and report from VisualStudio about memory leak made me believe that smth is very wrong ))
Buffer easily reduced to much smaller size.

How to read the model of monitor from the EDID?

In the registry there is one (or more) key depending how many monitors you have HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY\DEL404C{Some Unique ID}\Device Parameters\EDID which is a REG_BINARY key. In my case this is :
00 ff ff ff ff ff ff 00 4c 2d 6f 03 39 31 59 4d
07 12 01 03 0e 29 1a 78 2a 80 c5 a6 57 49 9b 23
12 50 54 bf ef 80 95 00 95 0f 81 80 81 40 71 4f
01 01 01 01 01 01 9a 29 a0 d0 51 84 22 30 50 98
36 00 ac ff 10 00 00 1c 00 00 00 fd 00 38 4b 1e
51 0e 00 0a 20 20 20 20 20 20 00 00 00 fc 00 53
79 6e 63 4d 61 73 74 65 72 0a 20 20 00 00 00 ff
00 48 56 44 51 32 30 36 37 37 37 0a 20 20 00 ef
My question is how can I read only model of monitor ("SyncMaster" for example) and not all of the information using C or C++?
The format of EDID is described here: http://en.wikipedia.org/wiki/Extended_display_identification_data
What you're interested in here is the descriptor blocks of the EDID, which are found in the byte ranges 54-71, 72-89, 90-107, and 108-125. Here's those four blocks in your EDID:
#1: 9a29 a0d0 5184 2230 5098 3600 acff 1000 00
#2: 0000 00fd 0038 4b1e 510e 000a 2020 2020 20
#3: 0000 00fc 0053 796e 634d 6173 7465 720a 20
#4: 0000 00ff 0048 5644 5132 3036 3737 370a 00
You can identify the descriptor containing the monitor name because the first three bytes are all zero (so it isn't a detailed timing descriptor), and the fourth one byte FC (indicating the type). The fifth byte and beyond contain the name, which is here:
5379 6e63 4d61 7374 6572 0a20 SyncMaster..
So, in short: Check at offsets 54, 72, 90, and 108 for the sequence 00 00 00 FC; if you find a match, the monitor name is the next 12 bytes.

vbscript match within a match

Good day all.
I am running some Cisco show commands on a router. I am capturing the output to an array. I want to use Regex to find certain information in the output. The Regex works in the sense that it find the line containing it however there is not enough unique information I can create my regex with so I end up with more that I want. Here is the output:
ROUTERNAME#sh diag
Slot 0:
C2821 Motherboard with 2GE and integrated VPN Port adapter, 2 ports
Port adapter is analyzed
Port adapter insertion time 18w4d ago
Onboard VPN : v2.3.3
EEPROM contents at hardware discovery:
PCB Serial Number : FOC1XXXXXXXXX
Hardware Revision : 1.0
Top Assy. Part Number : 800-26921-04
Board Revision : E0
Deviation Number : 0
Fab Version : 03
RMA Test History : 00
RMA Number : 0-0-0-0
RMA History : 00
Processor type : 87
Hardware date code : 20090816
Chassis Serial Number : FTXXXXXXXXXX
Chassis MAC Address : 0023.ebf4.5480
MAC Address block size : 32
CLEI Code : COMV410ARA
Product (FRU) Number : CISCO2821
Part Number : 73-8853-05
Version Identifier : V05
EEPROM format version 4
EEPROM contents (hex):
0x00: 04 FF C1 8B 46 4F 43 31 33 33 33 31 4E 36 34 40
0x10: 03 E8 41 01 00 C0 46 03 20 00 69 29 04 42 45 30
0x20: 88 00 00 00 00 02 03 03 00 81 00 00 00 00 04 00
0x30: 09 87 83 01 32 8F C0 C2 8B 46 54 58 31 33 33 36
0x40: 41 30 4C 41 C3 06 00 23 EB F4 54 80 43 00 20 C6
0x50: 8A 43 4F 4D 56 34 31 30 41 52 41 CB 8F 43 49 53
0x60: 43 4F 32 38 32 31 20 20 20 20 20 20 82 49 22 95
0x70: 05 89 56 30 35 20 D9 02 40 C1 FF FF FF FF FF FF
AIM Module in slot: 0
Hardware Revision : 1.0
Top Assy. Part Number : 800-27059-01
Board Revision : A0
Deviation Number : 0-0
Fab Version : 02
PCB Serial Number : FOXXXXXXXXX
RMA Test History : 00
RMA Number : 0-0-0-0
RMA History : 00
Product (FRU) Number : AIM-VPN/SSL-2
Version Identifier : V01
EEPROM format version 4
EEPROM contents (hex):
0x00: 04 FF 40 04 F4 41 01 00 C0 46 03 20 00 69 B3 01
0x10: 42 41 30 80 00 00 00 00 02 02 C1 8B 46 4F 43 31
0x20: 33 33 31 36 39 59 55 03 00 81 00 00 00 00 04 00
0x30: CB 8D 41 49 4D 2D 56 50 4E 2F 53 53 4C 2D 32 89
0x40: 56 30 31 00 D9 02 40 C1 FF FF FF FF FF FF FF FF
0x50: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0x60: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0x70: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
What I want to capture is the Model number that is contained in the 'Product (FRU) Number:' section. In this example 'CISCO2821'. I want to output or MsgBox just the CISCO2821 although other possibilities could be 'CISCO2911/K9' or something similar.
This is the regex pattern I am using:
Product\s\(FRU\)\sNumber\s*:\s*CIS.*
Using a regex testing tool I was able to match the entire line containing what I want but I want to write only the model number.
I looked at 'ltrim' and 'rtrim' but did not think that could do it.
Any help would be greatly appreciated.
Regards.
Ok, this is in VB.NET not vbscript, but this may help get you on your way:
Dim RegexObj As New Regex("Product\s\(FRU\)\sNumber[\s\t]+:\s(CIS.+?)$", RegexOptions.IgnoreCase Or RegexOptions.Multiline)
ResultString = RegexObj.Match(SubjectString).Groups(1).Value
Invest in 2 little helper functions:
Function qq(sT) : qq = """" & sT & """" : End Function
Function newRE(sP, sF)
Set newRE = New RegExp
newRE.Pattern = sP
newRE.Global = "G" = Mid(sF, 1, 1)
newRE.IgnoreCase = "I" = Mid(sF, 2, 1)
newRE.MultiLine = "M" = Mid(sF, 3, 1)
End Function
and use
' 3 ways to skin this cat
Dim sInp : sInp = Join(Array( _
"CLEI Code: COMV410ARA" _
, "Product (FRU) Number : CISCO2821" _
, "Part Number:73-8853-05" _
), vbCrLf) ' or vbLf, vbCr
WScript.Echo sInp
' (1) just search for CIS + sequence of non-spaces - risky if e.g. CLEI Code starts with CIS
WScript.Echo 0, "=>", qq(newRE("CIS\S+", "gim").Execute(sInp)(0).Value)
' (2) use a capture/group (idea stolen from skyburner; just 'ported' to VBScript)
WScript.Echo 1, "=>", qq(newRE("\(FRU\)[^:]+:\s(\S+)", "gim").Execute(sInp)(0).Value)
WScript.Echo 2, "=>", qq(newRE("\(FRU\)[^:]+:\s(\S+)", "gim").Execute(sInp)(0).SubMatches(0))
' (3) generalize & use a Dictionary
Dim dicProps : Set dicProps = CreateObject("Scripting.Dictionary")
Dim oMT
For Each oMT in newRe("^\s*(.+?)\s*:\s*(.+?)\s*$", "GiM").Execute(sInp)
Dim oSM : Set oSM = oMT.SubMatches
dicProps(oSM(0)) = oSM(1)
Next
Dim sName
For Each sName In dicProps.Keys
WScript.Echo qq(sName), "=>", qq(dicProps(sName))
Next
to get this output:
CLEI Code: COMV410ARA
Product (FRU) Number : CISCO2821
Part Number:73-8853-05
0 => "CISCO2821"
1 => "(FRU) Number : CISCO2821"
2 => "CISCO2821"
"CLEI Code" => "COMV410ARA"
"Product (FRU) Number" => "CISCO2821"
"Part Number" => "73-8853-05"
and - I hope - some food for thought.
Important
a (plain) pattern matches/finds some part of the input
captures/groups/submatches/parentheses cut parts from this match
sometimes dealing with a generalized version of the problem gives
you more gain for less work