Worksheet Creation - python

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")

Related

How to write right to left in text file with 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 ??

int and string errors in the class file in Python

I am writing a python program where I have 3 files. One is the main file, one is the class file and one is data file. The data file reads from 2 text files and splits and arranges the data for use by the class and main file. Anyways, I am pretty much done with the data and main files but I am having problems with the class file. Its a general string formatting issue but I am failing to understand what I can possibly do to fix it. I am getting the error
" File "/Users/admin/Desktop/Program 6/FINAL/classFile.py", line 83,
in repr
if len(self._birthDay[0])<2: TypeError: object of type 'int' has no len()
Use string formatting, not string concatenation, it's much cleaner:
return "{} {} (# {} ) GPA {:0.2f}".format(
self._first, self._last, self._techID, self.currentGPA()
)
Plus if you use this format, it will auto-convert the type for you
It seems to me like birthDay is a list of ints, not a list of strings.
If you want to make sure they're all strings, you can try:
self._birthDay = list(map(str, birthDay))
Alternatively, if you know that they are all strings, you can use string formatting in the first place to avoid these len checks:
self._birthDay = ['{:02d}'.format(x) for x in birthDay]
Even better, though, would be to represent birthDay as a datetime.datetime object. Assuming it always comes in as 3 ints, Month, Day, Year, you'd do:
bmon, bday, byear = birthDay
self._birthDay = datetime.datetime(byear, bmon, bday)
Then your __repr__ can make use of the datetime.strftime method.
Edit
In response to your update, I think you should add from datetime import datetime to the top of getData, then instead of parsing out the month/day/year, use:
birthDay = datetime.strptime(x[3], '%m/%d/%Y')
This will get you a full-fledged datetime object to represent the birthdate (alternatively, you can use a datetime.date object, since you don't need the time).
Then you can replace your __repr__ method with:
def __repr__(self):
fmtstr = '{first} {last} (#{techid})\nAge: {age} ({bday})\nGPA: {gpa:0.2f} ({credits})'
bday = self._birthDay.strftime('%m/%d/%Y')
return fmtstr.format(first=self._first,
last=self._last,
age=self.currentAge(),
bday=bday,
gpa=self.currentGPA(),
credits=self._totalCredits)
Oh, and since _birthDay is now a datetime.datetime, you need to update currentAge() to return int((datetime.datetime.now() - self._birthDay) / datetime.timedelta(days=365)) That will be reasonably accurate without being too complicated.
As the error message states, len doesn't make sense with an int. If you want the number of characters in it, convert it to an str first.
def __repr__(self):
if len(str(self._birthDay[0]))<2:
self._birthDay[0] = "0" + str(self._birthDay[0])
elif len(str(self._birthDay[1]))<2:
self._birthDay[1] = "0" + str(self._birthDay[1])
return self._first + " " + self._last + " (#" + self._techID + ")\nAge: " + str(self.currentAge()) + \
" (" + str(self._birthDay[0]) + "/" + str(self._birthDay[1]) + "/" + str(self._birthDay[2]) + ")" + \
"\nGPA: %0.2f" % (self.currentGPA()) + " (" + str(self._totalCredits) + " Credits" + ")\n"

Python, read and write file is cutting final output file to limited number of lines?

So I wrote a small script that will convert my g-code file commands by replacing "G01" to "G1" it is all working perfectly but these files are very big they can end up with more then 10 or 20k lines of code!
My problem is that file with all code converted ends up with 4715 lines but original file has 4817 lines. Funny thing is the for loop is going through all lines but only first 4715 are written(I checked that by simple a = a + 1 every time something is written to a file)!
Here is the code it is very simple!
import string
a = 0
b = 0
s = open("test.gcode","r+")
replaced = open("test_replaced.gcode","a")
for line in s.readlines():
if "G01" in line:
replaced.write(line.replace("G01", "G1" ))
print ("G01 ==> G1")
a = a + 1
elif "G00" in line:
replaced.write(line.replace("G00", "G0" ))
print ("G00 ==> G0")
a = a + 1
else:
replaced.write(line.replace("******", "**" ))
print ("***")
a = a + 1
b = b + 1
#replaced.write(line.replace("G01", "G1" ))
#replaced.write(line.replace("G00", "G0" ))
print ("Done! - " + str(a) + " number of operations done!")
print ("Loopcount: " + str(b))
s.close()
As pointed out in a comment to your question, you should probably replace your open() statements with with statements. So, your code would become.
...
with open("test.gcode","r+") as s:
with open("test_replaced.gcode","a") as replaced:
...
print ("Done! - " + str(a) + " number of operations done!")
print ("Loopcount: " + str(b))
Please note that there is no longer a close() at the end of the script because the context manager (with) closes the file already.
All you code dealing with the files needs to be within the with blocks.
You can find more information about context managers here.

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.

Python - Trying to check input against range, then convert the variable into a string to be concatenated

first time posting here. I have searched high and low to figure out a way to do this, but I either don't understand how to apply existing answers to my code.
What I am trying to do is this: I want to take user input (a year), make sure it's between a range of years, and then if it is, concatenate it with an existing string as a variable.
The result of this code is that I get through and give all the necessary inputs, and then it fails with "fullInstr = str("cp -r /mnt/data/archive"+ fquery+ "/" + yquery+mquery+dquery+"/"+hquery+"*" + " " + outl2)
TypeError: cannot concatenate 'str' and 'int' objects"
import os
import sys
os.system("clear")
overW = str("0")
outf = str("/autocopy.sh") # Output file full path and file name
if os.path.isfile("/autocopy.sh"): #
overW = raw_input("This will overwrite the previous version. Do you want to continue? (y/n) ")
os.system("clear")
else:
os.system("clear")
if overW != "y":
os.system("clear")
sys.exit("No changes made.\n\n")
else:
os.system("clear")
#! Could also prompt for output file name, depending on how army-proof this needs to be.
finishMessage = "Finished."
outl = str("0") # Copy-to location
outl2 = str("0") # Modified Copy-to location
fquery = str("0") # A or B location variable
yquery = int("0") # Year variable
mquery = int("0") # Month variable
dquery = int("0") # Day variable
hquery = str("0") # Hour variable
mh1 = int("0") # Modified starting hour after transformation
mh2 = int("0") # Modified ending hour after transformation
mpath = str("0") # makes path if needed
fullInstr = str("0") # Full command set to write to file
formatList = (['A', 'B'])
yearList = list(range(2000,2099))
#monthList = (['01']-['12'])
#! hquery is going to have to parse for ranges
# Instruction header
print "Builds a script to automatically copy folders and files from the storage array to a location of your choosing.\n"
print "Valid inputs for the questions below are numeric."
print "Year would be the full year, i.e. 2013"
print "Month is the two-digit month, i.e. 10"
print "Day is the two-digit day, i.e. 22"
print "Hour or hour range is just the first two digits of the hours you want to copy. i.e. 15 or 00-23\n\n"
outl = raw_input("Where do you want to copy the files to? Type the full path: ")
while not os.path.exists(outl):
mpath = raw_input ("\nThat path doesn't exist on this system. Do you want to create it? (y/n) ")
if mpath != "y":
outl = raw_input("Where do you want to copy the files to? Type a valid path: ")
else:
os.mkdir(outl)
print "\n"
if not outl.endswith("/"):
outl2 = outl + "/"
fquery = raw_input("Do you want to copy A or B? ")
while not(fquery in formatList):
print "\nInvalid input. You have to choose one of the two as printed above."
fquery = raw_input("\nDo you want to copy A or B? ")
print "\n"
yquery = int(raw_input("What year? "))
while yquery not in yearList:
print "\nInvalid input. You have to choose a year in this century."
yquery = int(raw_input("\nWhat year? "))
print "\n"
mquery = raw_input("What day? ")
#! Valid months are 01 to 12
dquery = raw_input("What day? ")
#! Valid days are 01 to 31
hquery = raw_input("What hour or hour range? ")
#! if input is greater than two characters is must contain a - character
#! if is not 00-23, separate first and last numbers and write a line for each. If it isn't a range, don't transform it.
#os.system("touch " + outf)
#! if no error keep going
fullInstr = str("cp -r /mnt/data/archive"+ fquery+ "/" + yquery+mquery+dquery+"/"+hquery+"*" + " " + outl2)
os.system("echo "+fullInstr+ "> /autocopy.sh")
#os.system("chmod u+x "+outf) # Makes the output file executable
#! if error = 0 set finishMessage to print "Your shell script is complete and is ready to run. Run it by typing ." + outf
#! if error is <> 0 set finishMessage to print "Wasn't able to make the output file executable automatically. Use chmod to modify the file permissions manually on the file "+outf
#os.system("clear")
print finishMessage+"\n\n"
Stuff that is commented out is either not working or not implemented yet. I know the code quality is probably not the best, but this is my first time coding to do something I require. I have tried a lot of things like yquery = str(yquery) or just changing the fullInstr string to have str(yquery) in it and I can not get it to work. I am becoming frustrated.
You should use format for string formatting to avoid worrying about the type of variable being concatenated.
fullInstr = "cp -r /mnt/data/archive/{0}/{1}{2}{3}/{4}* {5}".format(fquery,yquery,mquery,dquery,hquery,out12)
That is because you need to convert the int to a str object.
fullInstr = str("cp -r /mnt/data/archive" + fquery + "/" + str(yquery) + mquery + dquery + "/" + hquery + "*" + " " + ^
outl2) ^
# ^ -> Use str to convert
The above code worked on my machine. Running windows 8. Python 2.7.5. I just had to change clear to cls.

Categories

Resources