Hex dump of a list of 16-bit numbers

Multi tool use
This is some code which prints a hexdump of a list of 16 bit numbers, at 16 bytes distance for each, after the "print data" comment:
#!/usr/bin/python3
# creating test data
data =
for i in range(500):
data = data + [ i & 0xff, i >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
# print data
c = 0
out = ""
for i in range(int(len(data) / 16)):
if i == 512: break
low = data[i * 16]
high = data[i * 16 + 1]
d = low | (high << 8)
out = out + ("%04x " % d)
if (i % 16) == 15: out = out + "n"
print(out)
It works, but I think I can write it simpler with "join" and maybe list comprehension? But shouldn't be a cryptic one-liner or something, I'm just looking for a more idiomatic Python solution. I want to print the first 512 numbers, but the data array can be shorter or longer.
python formatting number-systems
add a comment |
This is some code which prints a hexdump of a list of 16 bit numbers, at 16 bytes distance for each, after the "print data" comment:
#!/usr/bin/python3
# creating test data
data =
for i in range(500):
data = data + [ i & 0xff, i >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
# print data
c = 0
out = ""
for i in range(int(len(data) / 16)):
if i == 512: break
low = data[i * 16]
high = data[i * 16 + 1]
d = low | (high << 8)
out = out + ("%04x " % d)
if (i % 16) == 15: out = out + "n"
print(out)
It works, but I think I can write it simpler with "join" and maybe list comprehension? But shouldn't be a cryptic one-liner or something, I'm just looking for a more idiomatic Python solution. I want to print the first 512 numbers, but the data array can be shorter or longer.
python formatting number-systems
add a comment |
This is some code which prints a hexdump of a list of 16 bit numbers, at 16 bytes distance for each, after the "print data" comment:
#!/usr/bin/python3
# creating test data
data =
for i in range(500):
data = data + [ i & 0xff, i >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
# print data
c = 0
out = ""
for i in range(int(len(data) / 16)):
if i == 512: break
low = data[i * 16]
high = data[i * 16 + 1]
d = low | (high << 8)
out = out + ("%04x " % d)
if (i % 16) == 15: out = out + "n"
print(out)
It works, but I think I can write it simpler with "join" and maybe list comprehension? But shouldn't be a cryptic one-liner or something, I'm just looking for a more idiomatic Python solution. I want to print the first 512 numbers, but the data array can be shorter or longer.
python formatting number-systems
This is some code which prints a hexdump of a list of 16 bit numbers, at 16 bytes distance for each, after the "print data" comment:
#!/usr/bin/python3
# creating test data
data =
for i in range(500):
data = data + [ i & 0xff, i >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
# print data
c = 0
out = ""
for i in range(int(len(data) / 16)):
if i == 512: break
low = data[i * 16]
high = data[i * 16 + 1]
d = low | (high << 8)
out = out + ("%04x " % d)
if (i % 16) == 15: out = out + "n"
print(out)
It works, but I think I can write it simpler with "join" and maybe list comprehension? But shouldn't be a cryptic one-liner or something, I'm just looking for a more idiomatic Python solution. I want to print the first 512 numbers, but the data array can be shorter or longer.
python formatting number-systems
python formatting number-systems
edited 2 hours ago


200_success
128k15150413
128k15150413
asked 14 hours ago
Frank Buss
1235
1235
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Here are some comments on your code:
- I assume the structure of the input data is to be taken as it is: one long list where only the 1 out of 8 values contribute to the output.
c = 0
is defined but never used- It is not recommended to use compound statements (see PEP8 - "Other Recommendations"): use a separate line for an
if
and the statement under condition.
/
performs a true division (giving a float). To avoid switching betweenfloat
andint
, use integer division://
if i == 512: break
could me omitted if you would limit the range of thefor
loop immediately. Instead oflen(data)
usemin(512*16, len(data))
- The multiplication
i * 16
can be avoided if you use thestep
argument ofrange()
so thati
takes multiples of 16. - Instead of
"%04x " % d
use the newer f-strings
- Instead of calculating
d
, you could just passhigh
andlow
to the string template and format each independently. - Instead of
if (i % 16) == 15:
you could use a nested loop that deals with one output line - Your code produces a blank at the end of each line. That seems unnecessary. With
" ".join
you would not have this extra blank.
out
has a terminatingn
, butprint
also prints a newline as terminator (by default). With"n".join
you would not have this extra newline
Here is how it could look:
# Set a maximum to the output
length = min(512*16, len(data))
# Format data
lines =
for line in range(0, length, 256):
items =
for i in range(line, min(line+256, length), 16):
items.append(f"{data[i+1]:02x}{data[i]:02x}")
lines.append(" ".join(items))
out = "n".join(lines)
# Output
print(out)
Here is how the above data formatting translates when using list comprehension. You can split the expression over multiple lines to improve readability:
# Format data
out = "n".join([
" ".join([
f"{data[i+1]:02x}{data[i]:02x}"
for i in range(line, min(line + 256, length), 16)
])
for line in range(0, length, 256)
])
add a comment |
I like the improvements by @trincot. Another improvement would be to use constants instead of numbers, makes it easier to understand and change instead of using magic numbers scattered in the code. And the f-syntax is nice, but I don't want to install Python 3.6 on my Debian machine, it still runs Python 3.5 and might break things. And I might need the word later for other things as well, and it makes the intention more clear that it is a 16 bit word, so I kept my extra word calculation. And no need to collect all lines in a string, this was just a side product of my solution to avoid multiple lines with resetting the current line and then printing it.
My final code:
max_lines = 32
words_per_line = 16
step = 16
line_length = words_per_line * step
length = min(max_lines * line_length, len(data))
for line in range(0, length, line_length):
items =
for i in range(line, min(line + line_length, length), step):
d = data[i] + (data[i + 1] << 8)
items.append("%04x" % d)
print(" ".join(items))
Will be used for my ADC4 project, which returns 16 bytes per sample, which is the reason for the big step.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210628%2fhex-dump-of-a-list-of-16-bit-numbers%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here are some comments on your code:
- I assume the structure of the input data is to be taken as it is: one long list where only the 1 out of 8 values contribute to the output.
c = 0
is defined but never used- It is not recommended to use compound statements (see PEP8 - "Other Recommendations"): use a separate line for an
if
and the statement under condition.
/
performs a true division (giving a float). To avoid switching betweenfloat
andint
, use integer division://
if i == 512: break
could me omitted if you would limit the range of thefor
loop immediately. Instead oflen(data)
usemin(512*16, len(data))
- The multiplication
i * 16
can be avoided if you use thestep
argument ofrange()
so thati
takes multiples of 16. - Instead of
"%04x " % d
use the newer f-strings
- Instead of calculating
d
, you could just passhigh
andlow
to the string template and format each independently. - Instead of
if (i % 16) == 15:
you could use a nested loop that deals with one output line - Your code produces a blank at the end of each line. That seems unnecessary. With
" ".join
you would not have this extra blank.
out
has a terminatingn
, butprint
also prints a newline as terminator (by default). With"n".join
you would not have this extra newline
Here is how it could look:
# Set a maximum to the output
length = min(512*16, len(data))
# Format data
lines =
for line in range(0, length, 256):
items =
for i in range(line, min(line+256, length), 16):
items.append(f"{data[i+1]:02x}{data[i]:02x}")
lines.append(" ".join(items))
out = "n".join(lines)
# Output
print(out)
Here is how the above data formatting translates when using list comprehension. You can split the expression over multiple lines to improve readability:
# Format data
out = "n".join([
" ".join([
f"{data[i+1]:02x}{data[i]:02x}"
for i in range(line, min(line + 256, length), 16)
])
for line in range(0, length, 256)
])
add a comment |
Here are some comments on your code:
- I assume the structure of the input data is to be taken as it is: one long list where only the 1 out of 8 values contribute to the output.
c = 0
is defined but never used- It is not recommended to use compound statements (see PEP8 - "Other Recommendations"): use a separate line for an
if
and the statement under condition.
/
performs a true division (giving a float). To avoid switching betweenfloat
andint
, use integer division://
if i == 512: break
could me omitted if you would limit the range of thefor
loop immediately. Instead oflen(data)
usemin(512*16, len(data))
- The multiplication
i * 16
can be avoided if you use thestep
argument ofrange()
so thati
takes multiples of 16. - Instead of
"%04x " % d
use the newer f-strings
- Instead of calculating
d
, you could just passhigh
andlow
to the string template and format each independently. - Instead of
if (i % 16) == 15:
you could use a nested loop that deals with one output line - Your code produces a blank at the end of each line. That seems unnecessary. With
" ".join
you would not have this extra blank.
out
has a terminatingn
, butprint
also prints a newline as terminator (by default). With"n".join
you would not have this extra newline
Here is how it could look:
# Set a maximum to the output
length = min(512*16, len(data))
# Format data
lines =
for line in range(0, length, 256):
items =
for i in range(line, min(line+256, length), 16):
items.append(f"{data[i+1]:02x}{data[i]:02x}")
lines.append(" ".join(items))
out = "n".join(lines)
# Output
print(out)
Here is how the above data formatting translates when using list comprehension. You can split the expression over multiple lines to improve readability:
# Format data
out = "n".join([
" ".join([
f"{data[i+1]:02x}{data[i]:02x}"
for i in range(line, min(line + 256, length), 16)
])
for line in range(0, length, 256)
])
add a comment |
Here are some comments on your code:
- I assume the structure of the input data is to be taken as it is: one long list where only the 1 out of 8 values contribute to the output.
c = 0
is defined but never used- It is not recommended to use compound statements (see PEP8 - "Other Recommendations"): use a separate line for an
if
and the statement under condition.
/
performs a true division (giving a float). To avoid switching betweenfloat
andint
, use integer division://
if i == 512: break
could me omitted if you would limit the range of thefor
loop immediately. Instead oflen(data)
usemin(512*16, len(data))
- The multiplication
i * 16
can be avoided if you use thestep
argument ofrange()
so thati
takes multiples of 16. - Instead of
"%04x " % d
use the newer f-strings
- Instead of calculating
d
, you could just passhigh
andlow
to the string template and format each independently. - Instead of
if (i % 16) == 15:
you could use a nested loop that deals with one output line - Your code produces a blank at the end of each line. That seems unnecessary. With
" ".join
you would not have this extra blank.
out
has a terminatingn
, butprint
also prints a newline as terminator (by default). With"n".join
you would not have this extra newline
Here is how it could look:
# Set a maximum to the output
length = min(512*16, len(data))
# Format data
lines =
for line in range(0, length, 256):
items =
for i in range(line, min(line+256, length), 16):
items.append(f"{data[i+1]:02x}{data[i]:02x}")
lines.append(" ".join(items))
out = "n".join(lines)
# Output
print(out)
Here is how the above data formatting translates when using list comprehension. You can split the expression over multiple lines to improve readability:
# Format data
out = "n".join([
" ".join([
f"{data[i+1]:02x}{data[i]:02x}"
for i in range(line, min(line + 256, length), 16)
])
for line in range(0, length, 256)
])
Here are some comments on your code:
- I assume the structure of the input data is to be taken as it is: one long list where only the 1 out of 8 values contribute to the output.
c = 0
is defined but never used- It is not recommended to use compound statements (see PEP8 - "Other Recommendations"): use a separate line for an
if
and the statement under condition.
/
performs a true division (giving a float). To avoid switching betweenfloat
andint
, use integer division://
if i == 512: break
could me omitted if you would limit the range of thefor
loop immediately. Instead oflen(data)
usemin(512*16, len(data))
- The multiplication
i * 16
can be avoided if you use thestep
argument ofrange()
so thati
takes multiples of 16. - Instead of
"%04x " % d
use the newer f-strings
- Instead of calculating
d
, you could just passhigh
andlow
to the string template and format each independently. - Instead of
if (i % 16) == 15:
you could use a nested loop that deals with one output line - Your code produces a blank at the end of each line. That seems unnecessary. With
" ".join
you would not have this extra blank.
out
has a terminatingn
, butprint
also prints a newline as terminator (by default). With"n".join
you would not have this extra newline
Here is how it could look:
# Set a maximum to the output
length = min(512*16, len(data))
# Format data
lines =
for line in range(0, length, 256):
items =
for i in range(line, min(line+256, length), 16):
items.append(f"{data[i+1]:02x}{data[i]:02x}")
lines.append(" ".join(items))
out = "n".join(lines)
# Output
print(out)
Here is how the above data formatting translates when using list comprehension. You can split the expression over multiple lines to improve readability:
# Format data
out = "n".join([
" ".join([
f"{data[i+1]:02x}{data[i]:02x}"
for i in range(line, min(line + 256, length), 16)
])
for line in range(0, length, 256)
])
edited 5 hours ago
answered 9 hours ago


trincot
40937
40937
add a comment |
add a comment |
I like the improvements by @trincot. Another improvement would be to use constants instead of numbers, makes it easier to understand and change instead of using magic numbers scattered in the code. And the f-syntax is nice, but I don't want to install Python 3.6 on my Debian machine, it still runs Python 3.5 and might break things. And I might need the word later for other things as well, and it makes the intention more clear that it is a 16 bit word, so I kept my extra word calculation. And no need to collect all lines in a string, this was just a side product of my solution to avoid multiple lines with resetting the current line and then printing it.
My final code:
max_lines = 32
words_per_line = 16
step = 16
line_length = words_per_line * step
length = min(max_lines * line_length, len(data))
for line in range(0, length, line_length):
items =
for i in range(line, min(line + line_length, length), step):
d = data[i] + (data[i + 1] << 8)
items.append("%04x" % d)
print(" ".join(items))
Will be used for my ADC4 project, which returns 16 bytes per sample, which is the reason for the big step.
add a comment |
I like the improvements by @trincot. Another improvement would be to use constants instead of numbers, makes it easier to understand and change instead of using magic numbers scattered in the code. And the f-syntax is nice, but I don't want to install Python 3.6 on my Debian machine, it still runs Python 3.5 and might break things. And I might need the word later for other things as well, and it makes the intention more clear that it is a 16 bit word, so I kept my extra word calculation. And no need to collect all lines in a string, this was just a side product of my solution to avoid multiple lines with resetting the current line and then printing it.
My final code:
max_lines = 32
words_per_line = 16
step = 16
line_length = words_per_line * step
length = min(max_lines * line_length, len(data))
for line in range(0, length, line_length):
items =
for i in range(line, min(line + line_length, length), step):
d = data[i] + (data[i + 1] << 8)
items.append("%04x" % d)
print(" ".join(items))
Will be used for my ADC4 project, which returns 16 bytes per sample, which is the reason for the big step.
add a comment |
I like the improvements by @trincot. Another improvement would be to use constants instead of numbers, makes it easier to understand and change instead of using magic numbers scattered in the code. And the f-syntax is nice, but I don't want to install Python 3.6 on my Debian machine, it still runs Python 3.5 and might break things. And I might need the word later for other things as well, and it makes the intention more clear that it is a 16 bit word, so I kept my extra word calculation. And no need to collect all lines in a string, this was just a side product of my solution to avoid multiple lines with resetting the current line and then printing it.
My final code:
max_lines = 32
words_per_line = 16
step = 16
line_length = words_per_line * step
length = min(max_lines * line_length, len(data))
for line in range(0, length, line_length):
items =
for i in range(line, min(line + line_length, length), step):
d = data[i] + (data[i + 1] << 8)
items.append("%04x" % d)
print(" ".join(items))
Will be used for my ADC4 project, which returns 16 bytes per sample, which is the reason for the big step.
I like the improvements by @trincot. Another improvement would be to use constants instead of numbers, makes it easier to understand and change instead of using magic numbers scattered in the code. And the f-syntax is nice, but I don't want to install Python 3.6 on my Debian machine, it still runs Python 3.5 and might break things. And I might need the word later for other things as well, and it makes the intention more clear that it is a 16 bit word, so I kept my extra word calculation. And no need to collect all lines in a string, this was just a side product of my solution to avoid multiple lines with resetting the current line and then printing it.
My final code:
max_lines = 32
words_per_line = 16
step = 16
line_length = words_per_line * step
length = min(max_lines * line_length, len(data))
for line in range(0, length, line_length):
items =
for i in range(line, min(line + line_length, length), step):
d = data[i] + (data[i + 1] << 8)
items.append("%04x" % d)
print(" ".join(items))
Will be used for my ADC4 project, which returns 16 bytes per sample, which is the reason for the big step.
answered 2 hours ago
Frank Buss
1235
1235
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210628%2fhex-dump-of-a-list-of-16-bit-numbers%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
pcATQPDD,B