How to write right to left in text file with python? - python

I'm struggling to write with PYTHON 3 in text file a string which contains Hebrew which is a language who is wrote from right to left.
my issue is that i have one variable who contains Hebrew and I need to concatenate it to a bigger string , is name is record.
I wrote also an ljust() method which is just left align the string
Order_interface_2 = '$Order_interface_2$'.ljust(1)
Contract_num= '$Contract_num$'.ljust(12)
Item_num = '$Item_num$'.rjust(5)
Material_code = '$Material_code$'.ljust(18)
Item_cat = '$Item_cat$'.ljust(1)
Account_Category= '$Account_Category$'.ljust(1)
Material_group= '$Material_group$'.ljust(9)
Short_Text= '$Short_Text$'.ljust(40)
Indicator= '$Indicator$'.ljust(1)
Plant = '$Plant$'.ljust(4)
Order_unit = '$Order_unit$'.ljust(3)
Net_price = '$Net_price$'.rjust(25)
Tax_code = '$Tax_code$'.ljust(2)
PO_quantity= '$PO_quantity$'.rjust(15)
Update_info= '$Update_info$'.ljust(1)
Overdelivery= '$Overdelivery$'.ljust(1)
Underdelivery= '$Underdelivery$'.rjust(5)
Indicator_Goods= '$Indicator_Goods$'.ljust(1)
Non_Valuated_Goods= '$Non_Valuated_Goods$'.ljust(1)
Delivery_Comp= '$Delivery_Comp$'.ljust(1)
Final_invoice= '$Final_invoice$'.ljust(1)
record = Order_interface_2 + Contract_num + Item_num + Material_code + Item_cat + Account_Category + Material_group + Short_Text + Indicator + Plant + Order_unit + Net_price + Tax_code + PO_quantity + Update_info + Overdelivery +Underdelivery+ Indicator_Goods + Non_Valuated_Goods + Delivery_Comp + Final_invoice
print(record)
I concatenated all the variables together to get one big string => record
the Variable Short_Text contains the Hebrew string.
Now for the example I tried to wrote in English in my first try. So the Short_text was in English at this moment and it was like this, I highlighted the string in the row it wrote it like this :
first try in English
but when I changed to Hebrew , all the variables who come after that changed their positions
second try in hebrew
How can I do to get the same positions for those variables who come after Hebrew ??? as it was in English ??

Related

Worksheet Creation

I am trying to make a math worksheet for grade schoolers. I wanted to make it as a np.random.randint function to generate some 2-digit, 3-digit and 4-digit numbers then process the numbers to form a worksheet in the manner that a grade schooler is used to.
I having trouble joining the number generated to look like this 1
With my current code I got to this
q1=q2=[]
q1= [two_digit[0],two_digit[1]]
q2=[two_digit[2],two_digit[3]]
addition="+".join(map(str,q2))
print(addition)
this gives an output like this
55+50
is there a better way to manipulate int to become string then go into a format that can be printed out easily?
You can use new lines and the unicode upperscore.
questions = [q1, q2]
nr_of_digits = 2
for q in questions:
q = list(map(str,q))
print(" " + q[0] + "\n" + "+" + q[1] + "\n" + u'\u0305' * (nr_of_digits + 1) + "\n")

Python: CSV delimiter failing randomly

I have created a script which a number of random passwords are generated (see below)
import string
import secrets
import datetime
now = datetime.datetime.now()
T = now.strftime('%Y_%m_d')
entities = ['AA','BB','CC','DD','EE','FF','GG','HH']
masterpass = ('MasterPass' + '_' + T + '.csv')
f= open(masterpass,"w+")
def random_secure_string(stringLength):
secureStrMain = ''.join((secrets.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits + ('!'+'?'+'"'+'('+')'+'$'+'%'+'#'+'#'+'/'+':'+';'+'['+']'+'#')) for i in range(stringLength)))
return secureStrMain
def random_secure_string_lower(stringLength):
secureStrLower = ''.join((secrets.choice(string.ascii_lowercase)) for i in range(stringLength))
return secureStrLower
def random_secure_string_upper(stringLength):
secureStrUpper = ''.join((secrets.choice(string.ascii_uppercase)) for i in range(stringLength))
return secureStrUpper
def random_secure_string_digit(stringLength):
secureStrDigit = ''.join((secrets.choice(string.digits)) for i in range(stringLength))
return secureStrDigit
def random_secure_string_char(stringLength):
secureStrChar = ''.join((secrets.choice('!'+'?'+'"'+'('+')'+'$'+'%'+'#'+'#'+'/'+':'+';'+'['+']'+'#')) for i in range(stringLength))
return secureStrChar
for x in entities:
f.write(x + ',' + random_secure_string(6) + random_secure_string_lower(1) + random_secure_string_upper(1) + random_secure_string_digit(1) + random_secure_string_char(1) + ',' + T + "\n")
f.close()
I use pandas to get the code to import a list, so normally it is for 200-250 entities, not just the 8 in the example.
The issue comes every so often where it looks like the comma delimiter fails to be read (see row 6 of attached photo)
In all the cases I have had of this (multiple run throughs), it looks like the 10th character is a comma, the 4 before (characters 6-9) are as stated in the script, but then instead of generating 6 initial characters (from random_secure_string(6)), it is generating 5. Could this be causing the issue? If so, how do I fix this?
Thank you in advance
Wild guess, because the content of the csv file as text is required to make sure.
A csv is a Comma Separated Values text file. That means that it is a plain text files where fields are delimited with a separator, normally the comma (,). In order to allow text fields to contain commas or even new lines, they can be enclosed in quotes (normally ") or special characters can be escaped, normally with \.
That means that if a line contains abcdefg\,2020_05 the comma will not be interpreted as a separator.
How to fix:
CSV is a simple format, but with many corner cases. The rule is avoid to read or write it by hand. Just use the standard library csv module here:
...
import csv
...
with open(masterpass,"w+", newline='') as f:
wr = csv.writer(f)
for x in entities:
wr.writerow([x, random_secure_string(6) + random_secure_string_lower(1) + random_secure_string_upper(1) + random_secure_string_digit(1) + random_secure_string_char(1), T])
The writer will take care for special characters and ensure that appropriate encoding or escaping will be used

How do I get my code to show a certain number of characters from a text file

In my assignment i'm expected to look for a word and only return a set number of characters (which is 80, and 40 on each side surrounding the word), without the use of nltk or regex.
I've set my code up as so
open = open("a2.txt", 'r')
file2read = open.readlines()
name = 'word'
for line in file2read:
s2 = line.split ("\n", 1)
if name in line:
i = line.find(name)
half = (80 - len(name) - 2) // 2
left = line[i - half]
right = line[i + len(word) + half]
print(left + word + right)
but then my print out looks like this(updated screenshot) instead of the 80 character lines which i'm hoping to find.
Sorry if this is a really newbie error as i'm only 3 weeks into the program and i've been searching and can't seem to get the answer
Instead of doing readlines which might not be consistent due to differences in windows/Unix you can also read the entire text at once:
You don't need to separate it in lines:
with open('a2.txt', 'r') as file:
a = file.read()
name = 'word'
if name in a:
i = a.find(name)
half = (80 - len(name) - 2) // 2
left = a[i-half:i]
right = a[i+len(name):i + len(name) + half]
print(left + name + right)
This way you are reading the entire text at once. Finding your word and printing the necessary 80 characters. This is the output
ut. even know say trip tip sandwich. words describe it. meat eater, love it. b
If you want to make it work for all the words in the text. You will need to make a loop =) but that i'm sure you can figure it out by yourself!

Python - How to handle space as a value of a variable without quotes?

I have a string "bitrate:8000"
I need to convert it to "-bps 8000". Note that the parameter name is changed and so is the delimiter from ':' to space.
Also the delimiters are not fixed always, sometimes I would need to change from ':' to '-' using the same program.
The change rules are supplied as a config file which I am reading through the ConfigParser module. Something like:
[params]
modify_param_name = bitrate/bps
modify_delimiter = :/' '
value = 8000
In my program:
orig_param = modify_param_name.split('/')[0]
new_param = modify_param_name.split('/')[1]
orig_delimiter = modify_delimiter.split('/')[0]
new_delimiter = modify_delimiter.split('/')[1]
new_param_string = new_param + new_delimiter + value
However, this results in the string as below:
-bps' '8000
The question is how can I handle spaces without the ' ' quotes?
The reason why you're getting the ' ' string is probably related to the way you parse your modify_delimiter value.
You're reading that as a string, so that modify_delimiter == ":/' '".
When you're doing:
new_delimiter = modify_delimiter.split('/')[1]
Essentially modify_delimiter.split('/') gives you an array of [':', "' '"].
So when you're doing new_param_string = new_param + new_delimiter + value
, you are concatenating together 'bps' + "' '" + '8000'.
If your modify_delimiter contained the string ':/ ', this would work just fine:
>>> new_param_string = new_param + new_delimiter + value
>>> new_param_string
'bps 8000'
It has been pointed out that you're using ConfigParser. Unfortunatelly, I don't see an option for ConfigParser (either in python 2 or 3) to preserve trailing whitespaces - it looks like they're always stripped.
What I can suggest in that case is that you wrap your string in quotes entirely in your config file:
[params]
modify_param_name = bitrate/bps
modify_delimiter = ":/ "
And in your code, when you initialize modify_delimiter, strip the " on your own:
modify_delimiter = config.get('params', 'modify_delimiter').strip('"')
That way the trailing space will get preserved and you should get your desired output.

Python - splitting lines in txt file by semicolon in order to extract a text title...except sometimes the title has semicolons in it

So, I have an extremely inefficient way to do this that works, which I'll show, as it will help illustrate the problem more clearly. I'm an absolute beginner in python and this is definitely not "the python way" nor "remotely sane."
I have a .txt file where each line contains information about a large number of .csv files, following format:
File; Title; Units; Frequency; Seasonal Adjustment; Last Updated
(first entry:)
0\00XALCATM086NEST.csv;Harmonized Index of Consumer Prices: Overall Index Excluding Alcohol and Tobacco for Austria©; Index 2005=100; M; NSA; 2015-08-24
and so on, repeats like this for a while. For anyone interested, this is the St.Louis Fed (FRED) data.
I want to rename each file (currently named the alphanumeric code # the start, 00XA etc), to the text name. So, just split by semicolon, right? Except, sometimes, the text title has semicolons within it (and I want all of the text).
So I did:
data_file_data_directory = 'C:\*****\Downloads\FRED2_csv_3\FRED2_csv_2'
rename_data_file_name = 'README_SERIES_ID_SORT.txt'
rename_data_file = open(data_file_data_directory + '\\' + rename_data_file_name)
for line in rename_data_file.readlines():
data = line.split(';')
if len(data) > 2 and data[0].rstrip().lstrip() != 'File':
original_file_name = data[0]
These last 2 lines deal with the fact that there is some introductory text that we want to skip, and we don't want to rename based on the legend # the top (!= 'File'). It saves the 00XAL__.csv as the oldname. It may be possible to make this more elegant (I would appreciate the tips), but it's the next part (the new, text name) that gets really ugly.
if len(data) ==6:
new_file_name = data[0][:-4].split("\\")[-1] + '-' + data[1][:-2].replace(':',' -').replace('"','').replace('/',' or ')
else:
if len(data) ==7:
new_file_name = data[0][:-4].split("\\")[-1] + '-' + data[1].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[2][:-2].replace(':',' -').replace('"','').replace('/',' or ')
else:
if len(data) ==8:
new_file_name = data[0][:-4].split("\\")[-1] + '-' + data[1].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[2].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[3][:-2].replace(':',' -').replace('"','').replace('/',' or ')
else:
if len(data) ==9:
new_file_name = data[0][:-4].split("\\")[-1] + '-' + data[1].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[2].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[3].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[4][:-2].replace(':',' -').replace('"','').replace('/',' or ')
else:
if len(data) ==10:
new_file_name = data[0][:-4].split("\\")[-1] + '-' + data[1].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[2].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[3].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[4].replace(':',' -').replace('"','').replace('/',' or ') + '-' + data[5][:-2].replace(':',' -').replace('"','').replace('/',' or ')
else:
(etc)
What I'm doing here is that there is no way to know for each line in the .csv how many items are in the list created by splitting it by semicolons. Ideally, the list would be length 6 - as follows the key # the top of my example of the data. However, for every semicolon in the text name, the length increases by 1...and we want everything before the last four items in the list (counting backwards from the right: date, seasonal adjustment, frequency, units/index) but after the .csv code (this is just another way of saying, I want the text "title" - everything for each line after .csv but before units/index).
Really what I want is just a way to save the entirety of the text name as "new_name" for each line, even after I split each line by semicolon, when I have no idea how many semicolons are in each text name or the line as a whole. The above code achieves this, but OMG, this can't be the right way to do this.
Please let me know if it's unclear or if I can provide more info.

Categories

Resources