I created a module named smethod.py, which includes this code: (first def to make mixed cased letters lowercase and second to capitalize)
def LWR():
result=""
for i in range(0,len(s)):
value = ord(s[i])
if value>64 and value<91:
result+=chr(value+32)
else:
result+=chr(value)
s=result
print(s)
return
def TTL():
ssplit = s.split()
small_a = ord("a")
small_z = ord("z")
cap_a = ord("A")
delta = small_a - cap_a
for z in ssplit :
if small_a <= ord(z[0]) <= small_z:
l = chr(ord(z[0])-delta)
new = l + z[1:]
print(new, end=" ")
else:
print(s)
return
Then I opened a new file and did this:
import smethod
s = input("Enter your string")
print("The lowercase version is:" ,smethod.LWR)
print("Title version is: ",smethod.TTL)
============= RESTART: /Users/ezgibahadir/Documents/smethod2.py =============
enter your stringezgi bahadır
The lowercase version is: <function LWR at 0x1111b28c0>
Title version is: <function TTL at 0x1111413b0>
What is the reason?
There are many things that could be improved.
You said you called the file method.py, so why are you importing smethod?
Your functions LWR and TTL don't take any arguments. Both of them refer to s, where does that s come from?
Even if they did work, you don't call them. You need to do method.LWR().
You've declared that this is Python3, but you're using the print function like Python2.
Some other issues:
Giving function names as 3-letter capital codes is not the python way. Call them to_lower and to_upper or something instead.
Given that this process is super common, both of these functions are provided in the standard library, you don't even need separate functions.
You could just do:
import smethod
s = input("Enter your string")
print(f"The lowercase version is: {s.lower()}")
print(f"Title version is: {s.upper()}")
In order to recreate the full function with chr and ord, you should be declaring something like:
def to_lower(s):
# code here
return result
And then to call it:
s = 'Hello World!'
print(to_lower(s))
Related
I am learning some coding, and I am stuck with an error I can't explain. Basically I want to read out a .csv file with birth statistics from the US to figure out the most popular name in the time recorded.
My code looks like this:
# 0:Id, 1: Name, 2: Year, 3: Gender, 4: State, 5: Count
names = {} # initialise dict names
maximum = 0 # store for maximum
l = []
with open("Filepath", "r") as file:
for line in file:
l = line.strip().split(",")
try:
name = l[1]
if name in names:
names[name] = int(names[name]) + int(l(5))
else:
names[name] = int(l(5))
except:
continue
print(names)
max(names)
def max(values):
for i in values:
if names[i] > maximum:
names[i] = maximum
else:
continue
return(maximum)
print(maximum)
It seems like the dictionary does not take any values at all since the print command does not return anything. Where did I go wrong (incidentally, the filepath is correct, it takes a while to get the result since the .csv is quite big. So my assumption is that I somehow made a mistake writing into the dictionary, but I was staring at the code for a while now and I don't see it!)
A few suggestions to improve your code:
names = {} # initialise dict names
maximum = 0 # store for maximum
with open("Filepath", "r") as file:
for line in file:
l = line.strip().split(",")
names[name] = names.get(name, 0) + l[5]
maximum = [(v,k) for k,v in names]
maximum.sort(reversed=True)
print(maximum[0])
You will want to look into Python dictionaries and learn about get. It helps you accomplish the objective of making your names dictionary in less lines of codes (more Pythonic).
Also, you used def to generate a function but you never called that function. That is why it's not printing.
I propose the shorted code above. Ask if you have questions!
Figured it out.
I think there were a few flow issues: I called a function before defining it... is that an issue or is python okay with that?
Also I think I used max as a name for a variable, but there is a built-in function with the same name, that might cause an issue I guess?! Same with value
This is my final code:
names = {} # initialise dict names
l = []
def maxval(val):
maxname = max(val.items(), key=lambda x : x[1])
return maxname
with open("filepath", "r") as file:
for line in file:
l = line.strip().split(",")
name = l[1]
try:
names[name] = names.get(name, 0) + int(l[5])
except:
continue
#print(str(l))
#print(names)
print(maxval(names))
I'm using IfcOpenshell to read an .ifc file. make some changes, then write it to a new .ifc file. But IfcOpenshell is not writing the unicode the same way as it reads it.
I'm creating a script taht adds a pset with properties to each ifcelement. the value of these properties are copied from existing properties. So basically i'm creating a pset that gathers chosen information to a single place.
This has worked great until the existing values contained unicode utf-8.
It is read and decoded to show the correct value when printed, but it does not write the unicode the same way as it reads it.
I tried changing the unicode used in PyCharm, no luck. I found simular posts elsewhere without finding a fix.
From what i've read elsewhere it has something to do with the unicode encoder/decoder IfcOpenshell use, but i cant be sure.
def mk_pset():
global param_name
global param_type
global max_row
global param_map
wb = load_workbook(b)
sheet = wb.active
max_row = sheet.max_row
max_column = sheet.max_column
param_name = []
param_type = []
param_map=[]
global pset_name
pset_name = sheet.cell(row=2, column=1).value
for pm in range(2, max_row+1):
param_name.append((sheet.cell(pm, 2)).value)
param_type.append((sheet.cell(pm, 3)).value)
param_map.append((sheet.cell(pm,4)).value)
print(param_type,' - ',len(param_type))
print(param_name,' - ',len(param_name))
create_pset()
def create_pset():
ifcfile = ifcopenshell.open(ifc_loc)
create_guid = lambda: ifcopenshell.guid.compress(uuid.uuid1().hex)
owner_history = ifcfile.by_type("IfcOwnerHistory")[0]
element = ifcfile.by_type("IfcElement")
sets = ifcfile.by_type("IfcPropertySet")
list = []
for sett in sets:
list.append(sett.Name)
myset = set(list)
global antall_parametere
global index
index = 0
antall_parametere = len(param_name)
if pset_name not in myset:
property_values = []
tot_elem = (len(element))
cur_elem = 1
for e in element:
start_time_e=time.time()
if not e.is_a() == 'IfcOpeningElement':
type_element.append(e.is_a())
for rel_e in e.IsDefinedBy:
if rel_e.is_a('IfcRelDefinesByProperties'):
if not rel_e[5][4] == None:
index = 0
while index < antall_parametere:
try:
ind1 = 0
antall_ind1 = len(rel_e[5][4])
while ind1 < antall_ind1:
if rel_e[5][4][ind1][0] == param_map[index]:
try:
if not rel_e[5][4][ind1][2]==None:
p_type = rel_e[5][4][ind1][2].is_a()
p_verdi =rel_e[5][4][ind1][2][0]
p_t=param_type[index]
property_values.append(ifcfile.createIfcPropertySingleValue(param_name[index], param_name[index],ifcfile.create_entity(p_type,p_verdi),None),)
ind1 += 1
else:
ind1 +=1
except TypeError:
pass
break
else:
ind1 += 1
except AttributeError and IndexError:
pass
index += 1
index = 0
property_set = ifcfile.createIfcPropertySet(create_guid(), owner_history, pset_name, pset_name,property_values)
ifcfile.createIfcRelDefinesByProperties(create_guid(), owner_history, None, None, [e], property_set)
ifc_loc_edit = str(ifc_loc.replace(".ifc", "_Edited.ifc"))
property_values = []
print(cur_elem, ' av ', tot_elem, ' elementer ferdig. ',int(tot_elem-cur_elem),'elementer gjenstår. Det tok ',format(time.time()-start_time_e),' sekunder')
cur_elem += 1
ifcfile.write(ifc_loc_edit)
else:
###print("Pset finnes")
sg.PopupError("Pset er allerede oprettet i modell.")
I expect p_verdi written to be equal to the p_verdi read.
Original read (D\X2\00F8\X0\r):
#2921= IFCBUILDINGELEMENTPROXYTYPE('3QPADpsq71CHeCe7e3GDm5',#32,'D\X2\00F8\X0\r',$,$,$,$,'DA64A373-DB41-C131-1A0C-A07A0340DC05',$,.NOTDEFINED.);
Written (D\X4\000000F8\X0\r):
#2921=IFCBUILDINGELEMENTPROXYTYPE('3QPADpsq71CHeCe7e3GDm5',#32,'D\X4\000000F8\X0\r',$,$,$,$,'DA64A373-DB41-C131-1A0C-A07A0340DC05',$,.NOTDEFINED.);
Decoded to "Dør"
this happens to hard spaceing also:
('2\X2\00A0\X0\090')
prints correctly as:('2 090')
gets written:
('2\X4\000000A0\X0\090')
written form is unreadable by my ifc using software.
Not so much an answere as a workaround.
After more research i found out that most IFC reading software seems to not support X4 coding, so i made a workaround with regex. Basically finding everything and replacing \X4\0000 with \X2. This has worked with all the spec chars i've encountered so far. But as stated, is just a workaround that probably wont work for everyone.
def X4trans_2(target_file,temp_fil):
from re import findall
from os import remove,rename
dec_file = target_file.replace('.ifc', '_dec.ifc')
tempname = target_file
dec_list = []
with open(temp_fil, 'r+') as r,open(dec_file, 'w', encoding='cp1252') as f:
for line in r:
findX4 = findall(r'\\X4\\0000+[\w]+\\X0\\', str(line))
if findX4:
for fx in findX4:
X4 = str(fx)
newX = str(fx).replace('\\X4\\0000', '\X2\\')
line = line.replace(str(X4), newX) # print ('Fant X4')
f.writelines(line)
remove(temp_fil)
try:
remove(target_file)
except FileNotFoundError:
pass
rename(dec_file,tempname)
It basically opens the ifc as text, find and replace X4 with X2 and writes it again.
I have a piece of code. When I run this code. It is compiling but not showing any print result. I want to print the returned values from this function. Can someone please guide me where I'm wrong?
`def input_data(prefix):
datafiles=os.listdir('/home/zeri/Desktop/check2')
dictData={}
for df in datafiles:
if re.match(prefix,df) and
os.path.isfile('/home/zeri/Desktop/check2'+'/'+df):
hmax=locale.atof(df[3:])
print hmax
data=np.genfromtxt(df, delimiter=' ')
dictData[hmax]=data
return dictData,len(data[0])
int main():
a=input_data('xyz')
print a`
Python is not C. So, "int main()" does not work. Better remove this line altogether, although you can define a function called "main".
But probably you have mainly an indentation issue. I tried to fix this in the code below.
import locale
import numpy as np
import re
def input_data(prefix):
datafiles = os.listdir('/home/zeri/Desktop/check2')
dictData = {}
for df in datafiles:
if re.match(prefix, df) and os.path.isfile('/home/zeri/Desktop/check2' + '/' + df):
hmax = locale.atof(df[3:])
print hmax # use "print(a)" if on Python 3
data = np.genfromtxt(df, delimiter = ' ')
dictData[hmax] = data
return dictData, len(data[0])
a = input_data('xyz')
print a # use "print(a)" if on Python 3
By the way, I would not use regular expressions to filter files.
I am reading a list of states from a file into an list[]:
mystk = []
with open('state_list.txt') as csvfile:
readCSV = csv.reader(csvfile,delimiter=',')
for row in readCSV:
mystk.append(row)
After the read I am adding the values in to a list.
print(str(mystk[0]).strip())
i=0
while i < 10:
strList = mystk[i]
print('Print:',strList)
i = i +1
The output of the above is :
Print: ['AL']
Print: ['AK']
Print: ['AZ']
Print: ['AR']
Print: ['CA']
Print: ['CO']
Print: ['CT']
Print: ['DE']
Print: ['FL']
Print: ['GA']
I am trying to achieve the following:
Print: AL
Print: AK
Print: AZ
Print: AR
Print: CA
Print: CO
Print: CT
Print: DE
Print: FL
Print: GA
I guess I could write a function or loop to strip out the ['?'] using regex or code like this:
i=0
while i < 10:
strList = mystk[i]
strList = str(strList).replace("['", "")
strList = strList.replace("']", "")
print(' ','Print:',strList)
i = i +1
However I was hoping there was an easier way then the code above however I am new to python and if this is the only way then it works for me.
this are recommendations that I mention in my comment plus some other
import csv
def getTID(file='TID.csv', delim='\n'):
result = []
with open(file) as csvTID:
readCSV = csv.reader(csvTID, delimiter=delim)
for row in readCSV:
result.append( row[0] )
return result
stockList = getTID()
for x in stockList:
print(x)
here with the use of arguments give the function more flexibility and with default values I retain the original behavior that way you don't need to modify your code (or the name of the file) if you want to use your function with another file like 'TID_2.cvs' for example, in that case just call getTID('TID_2.cvs') and as the function don't do anything to some global variable you can have the data from 2 or more different files in different variables if you need it, for example
stockList1 = getTID('TID_1.cvs')
stockList2 = getTID('TID_2.cvs')
every line of the csv file is split by commas, to get the string joined by commas again, use str.join:
sep = ", "
for row in mystk:
print(' ', 'Print:', sep.join(row))
Guys thank you all very much, learning this is stuff is awesome. So many ways to do stuff. After reading your comments and understanding the concepts I have written the following function to get the stock list I need:
import csv
stockList = []
def getTID():
with open('TID.csv') as csvTID:
readCSV = csv.reader(csvTID,delimiter='\n')
for row in readCSV:
stockList.append((row[0]))
getTID()
for x in stockList[:]: print(x)
This returns the list as expected: VOD.L, APPL, etc.
My application offers the ability to the user to export its results. My application exports text files with name Exp_Text_1, Exp_Text_2 etc. I want it so that if a file with the same file name pre-exists in Desktop then to start counting from this number upwards. For example if a file with name Exp_Text_3 is already in Desktop, then I want the file to be created to have the name Exp_Text_4.
This is my code:
if len(str(self.Output_Box.get("1.0", "end"))) == 1:
self.User_Line_Text.set("Nothing to export!")
else:
import os.path
self.txt_file_num = self.txt_file_num + 1
file_name = os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt" + "_" + str(self.txt_file_num) + ".txt")
file = open(file_name, "a")
file.write(self.Output_Box.get("1.0", "end"))
file.close()
self.User_Line_Text.set("A text file has been exported to Desktop!")
you likely want os.path.exists:
>>> import os
>>> help(os.path.exists)
Help on function exists in module genericpath:
exists(path)
Test whether a path exists. Returns False for broken symbolic links
a very basic example would be create a file name with a formatting mark to insert the number for multiple checks:
import os
name_to_format = os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt_{}.txt")
#the "{}" is a formatting mark so we can do file_name.format(num)
num = 1
while os.path.exists(name_to_format.format(num)):
num+=1
new_file_name = name_to_format.format(num)
this would check each filename starting with Exp_Txt_1.txt then Exp_Txt_2.txt etc. until it finds one that does not exist.
However the format mark may cause a problem if curly brackets {} are part of the rest of the path, so it may be preferable to do something like this:
import os
def get_file_name(num):
return os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt_" + str(num) + ".txt")
num = 1
while os.path.exists(get_file_name(num)):
num+=1
new_file_name = get_file_name(num)
EDIT: answer to why don't we need get_file_name function in first example?
First off if you are unfamiliar with str.format you may want to look at Python doc - common string operations and/or this simple example:
text = "Hello {}, my name is {}."
x = text.format("Kotropoulos","Tadhg")
print(x)
print(text)
The path string is figured out with this line:
name_to_format = os.path.join(os.path.expanduser("~"), "Desktop", "Exp_Txt_{}.txt")
But it has {} in the place of the desired number. (since we don't know what the number should be at this point) so if the path was for example:
name_to_format = "/Users/Tadhg/Desktop/Exp_Txt_{}.txt"
then we can insert a number with:
print(name_to_format.format(1))
print(name_to_format.format(2))
and this does not change name_to_format since str objects are Immutable so the .format returns a new string without modifying name_to_format. However we would run into a problem if out path was something like these:
name_to_format = "/Users/Bob{Cat}/Desktop/Exp_Txt_{}.txt"
#or
name_to_format = "/Users/Bobcat{}/Desktop/Exp_Txt_{}.txt"
#or
name_to_format = "/Users/Smiley{:/Desktop/Exp_Txt_{}.txt"
Since the formatting mark we want to use is no longer the only curly brackets and we can get a variety of errors:
KeyError: 'Cat'
IndexError: tuple index out of range
ValueError: unmatched '{' in format spec
So you only want to rely on str.format when you know it is safe to use. Hope this helps, have fun coding!