I have an API that returns a pdf from json, but it just returns as a long string of integers like following
[{"status":"SUCCESS"},{"data":"37,80,68,70,45,49,46,52,10,37,-45,-21,-23,-31,10,49,32,48,32,111,98,106,10,60,60,47,84,105,116,108,101,32,40,49,49,32,67,83,45,73,73,32,32,83,117,98,106,101,99,116,105,118,101,32,81,46,...
...,1,32,49,55,10,47,82,111,111,116,32,56,32,48,32,82,10,47,73,110,102,111,32,49,32,48,32,82,62,62,10,115,116,97,114,116,120,114,101,102,10,54,55,54,56,53,10,37,37,69,79,70"}
My questions are:
What is this encoding?
How to convert this into a pdf using python?
P.S: Here is the endpoint to get the full response.
The beginning of data is a hint that you actually have a list of the bytes values of the PDF file: it starts with the byte values of '%PDF-1.4'.
So you must first extract that curious string:
data = json_data[1]['data']
to have:
"37,80,68,70,45,49,46,52,10,37,-45,-21,-23,-31,10,49,32,48,32,111,98,106,10,60,60,47,84,105,116,108,101,32,40,49,49,32,67,83,45,73,73,32,32,83,117,98,106,101,99,116,105,118,101,32,81,46, ..."
convert it to a list of int first, then a byte string (i if i >=0 else i+256 ensure positive values...):
intlist = [int(i) for i in data.split(",")]
b = bytes(i if i >=0 else i+256 for i in intlist)
to get b'%PDF-1.4\n%\xd3\xeb\xe9\xe1\n1 0 obj\n<</Title (11 CS-II Subjective Q...'
And finaly save that to a file:
with open('file.pdf', 'wb') as fd:
fd.write(b)
I've been writing Python code for only about 4 weeks. I'm writing a little text based game to learn and test everything I know. I can easily make this work with a value entered into the console as an integer, but for whatever reason I can't get my code to work with reading this value from a text file.
Earlier in the program, my code saves a value to a text file, just one value, then later it opens the same text file, over-writes the value with a new value based on a very simple calculation. That calculation is the first value, plus 5. I've spent a bunch of time reading on this site and going through my books and at this point I'm pretty sure I'm just missing something obvious.
The first piece of code that creates the doc and sets the value:
def set_hp(self):
f = open('player_hp.txt', 'w')
self.hitpoints = str(int(self.hitpoints))
f.write(self.hitpoints)
f.close()
This is the trouble section...I have commented the line with the problem.
def camp_fire():
print
print "You stop to build a fire and rest..."
print "Resting will restore your health."
print "You gather wood from the ground around you. You spark\n\
your flint against some tinder. A flame appears.\n\
You sit, and close your eyes in weariness. A peaceful calm takes you\n\
into sleep."
f = open('player_hp.txt', 'r')
orig_hp = f.readlines()
orig_hp = str(orig_hp)
f = open('player_hp.txt', 'w')
new_value = orig_hp + 5 ##this is where my code breaks
new_value = str(int(new_value))
f.write(new_value)
f.close()
print "You have gained 5 hitpoints from resting. Your new HP are {}.".format(new_value)
This is the error I get:
File "C:\Python27\Awaken03.py", line 300, in camp_fire
new_value = orig_hp + 5
TypeError: cannot concatenate 'str' and 'int' objects
I know you can't concatenate a string and an integer, but I keep trying different methods to convert the string to an integer to do the quick math, but I can't seem to get it right.
Error message is clear, you are trying to concatenate string with an integer. You should change the line from:
new_value = orig_hp + 5
To:
new_value = str(int(orig_hp) + 5)
Then you can use above value to write directly into file as a string as:
##new_value = str(int(new_value))## Skip this line
f.write(new_value)
f.readlines() returns a list of lines, in your case something like ['10']. So str(orig_hp) is a textual representation of this list, like '[\'10\']', which you won't be able to interpret as an integer.
You can just use f.read() to read the whole file at once in a string, which will be something like '10', and convert it to a integer:
orig_hp = int(f.read())
I wrote a function to see encrypt a given text file. The below code is a small portion of the function.
#pad it before encrypting it
elif len(chunk) % 16 != 0:
chunk += ' ' * (16 - len(chunk) % 16)
#write encrypted data into output file
out_file.write(encryptor.encrypt(chunk))
Whenever I try to use the function I get an error that points to the last line saying
"TyprError: can't concat str to bytes". I'm not sure what I need to do in order to fix this error. I've tried a few things and they end leading me into more similar errors. Any guidance would be greatly appreciated.
The encryptor is below.
encryptor = PKCS1_OAEP.new(pub_key)
Your encryption method encryptor.encrypt() very likely accepts bytes as argument, not str. It also returns bytes very likely. So I suggest you to use the encode/decode methods as follows (example of utf-8 coding):
out_file.write(encryptor.encrypt(chunk.encode('utf-8')).decode('utf-8'))
You are trying to mix and match incompatible data types. Here is an example that will throw the same error:
str1 = bytes(123)
str2 = str(123)
str1 + str2
Go through your example and find where you are trying to concat a bytes value to a str value and make them match types.
I can't seem to get this program I'm supposed to do for a project to output the correct output, even though I have tried getting it to work multiple times. The project is:
Your program needs to decode an encrypted text file called "encrypted. txt". The person who wrote it used a cipher specified in "key. txt". This key file would look similar to the following:
A B
B C
C D
D E
E F
F G
G H
H I
I J
J K
K L
L M
M N
N O
O P
P Q
Q R
R S
S T
T U
U V
V W
W X
X Y
Y Z
Z A
The left column represents the plaintext letter, and the right column represents the corresponding ciphertext.
Your program should decode the "encrypted.txt" file using "key.txt" and write the plaintext to "decrypted.txt".
Your program should handle both upper and lower case letters in the encrypted without having two key files (or duplicating keys). You may have the decrypted text in all caps.
You should be able to handle characters in the encrypted text that are not in your key file. In that case, just have the decryption repeat the character. This will allow you to have spaces in your encrypted text that remain spaces when decrypted.
While you may write a program to create the key file - do NOT include that in the submission. You may manually create the encrypted and key text files. Use either the "new file" option in Python Shell (don't forget to save as txt) or an editor such as notepad. Do not use word.
Here is my code:
keyFile = open("key.txt", "r")
keylist1= []
keylist2 = []
for line in keyFile:
keylist1.append(line.split()[0])
keylist2.append(line.split()[1])
keyFile.close()
encryptedfile = open("encrypted.txt", "r")
lines = encryptedfile.readlines()
currentline = ""
decrypt = ""
for line in lines:
currentline = line
letter = list(currentline)
for i in range(len(letter)):
currentletter = letter[i]
if not letter[i].isalpha():
decrypt += letter[i]
else:
for o in range(len(keylist1)):
if currentletter == keylist1[o]:
decrypt += keylist2[o]
print(decrypt)
The only output I get is:
, ?
which is incorrect.
You forgot to handle lowercase letters. Use upper() to convert everything to a common case.
It would also be better to use a dictionary instead of a pair of lists.
mapping = {}
with open("key.txt", "r") as keyFile:
for line in keyFile:
l1, l2 = line.split()
mapping[upper(l1)] = upper(l2)
decrypt = ""
with open("encrypted.txt", "r") as encryptedFile:
for line in encryptedFile:
for char in line:
char = upper(char)
if char in mapping:
decrypt += mapping[char]
else:
decrypt += char
print(decrypt)