How to use sep parameter in .format? - python

I just started learning python and I'm experimenting new things.
isim = input("Name:")
soyad = input("Surname:")
yaş = input("Age:")
edu = input("Education:")
gen = input("Gender:")
print("Name: {},Surname: {},Age: {},Education: {},Gender: {}".format(
isim,soyad,yaş,edu,gen))
My aim is to use \n after all brackets ({}) so I'll be able to print them more organised but I don't want to use \n after every part.
print(a,b,c,d,e,sep = \n)
is the only way I know. I want to use sep and format together. How can I do that?

You're only printing one string created by using format so sep doesn't apply. You could expand a generator expression that adds "\n" to each argument to format, though.
print("Name: {},Surname: {},Age: {},Education: {},Gender: {}".format(
*(f"{x}\n" for x in [isim,soyad,yaş,edu,gen])))
You may instead wish to use a multi-line f-string, though.
print(f"""Name: {isim}
Surname: {soyad}
Age: {yaş}
Education: {edu}
Gender: {gen}""")

Personally, I'd just format your print statement like:
print(f"Name: {isim}",f"Surname: {soyad}",f"Age: {yaş}",f"Education: {edu}",f"Gender: {gen}", sep='\n')
# OR
print(f"Name: {isim}\nSurname: {soyad}\nAge: {yaş}\nEducation: {edu}\nGender: {gen}")

As an alternative to #Chris's comprehensive answer, you can simply apply replace before formatting your string:
print("Name: {},Surname: {},Age: {},Education: {},Gender: {}".replace('{}', '{}\n').format(isim,soyad,yaş,edu,gen))

A systematical approach which depends entirely on the type of field entries. Data stored into dictionary, then a single string is constructed using format and join.
# fields names
fields = ("Name",
"Surname",
"Age",
"Education",
"Gender")
# used a dictionary to store the input results
data = {field: input(field) for field in fields}
# key-value template
template_string = '{}: {{}}'
# add the keys
field_names = map(template_string.format, data)
# add the values (with separator ",\n")
result = ',\n'.join(field_names).format(*data.values())
# check result
print(result)
Another similar way could be to use the "var=" property of f-strings. Requirement: the variables identifiers should be chosen properly since they will part of the final string. Side-effect: there are = around... if no conflicts they can be substituted with
Name = input("Name:")
Surname = input("Surname:")
Age = input("Age:")
Education = input("Education:")
Gender = input("Gender:")
# var= property of f-string
result = f'{Name=}\n{Surname=}\n{Age=}\n{Education=}\n{Gender=}'
# if no conflicts with = symbol
result = result.replace('=', ': ')
print(result)
How to use format and sep together? Taking as reference the approach in the question: a list is required, if no conflicts with other characters, split it at ,:
# ...
result = "Name: {},Surname: {},Age: {},Education: {},Gender: {}".format(isim,soyad,yaş,edu,gen)
print(*result.split(','), sep='\n')

Related

Creating User Name from Name in Python

I have a spreadsheet with data. There I have a name like Roger Smith. I would like to have the user name rsmith.
Therefore, the first letter of the first name followed by the family name. How can I do this in Python?
def make_username(full_name: str) -> str:
first_names, last_name = full_name.lower().rsplit(maxsplit=1)
return first_names[0] + last_name
print(make_username("Roger M. Smith"))
Output: rsmith
The use of rsplit is to ensure that in case someone has more than one first name, the last name is still taken properly. I assume that last names will not have spaces in them.
Note however that depending on your use case, you may need to perform additional operations to ensure that you don't get duplicates.
By passing the 0 index to the full name we get the first letter of the name.
Using the split() function we can convert the full_name into list. Then passing -1 index we can get the family name.
Lower() will convert the name into lower case.
full_name = 'Roger Smith'
username = full_name[0] + full_name.split()[-1]
print(username.lower())
#output : rsmith
Here's an option in case you are also interested in generating usernames using last name followed by first letter of first name:
name = 'Roger R. Smith'
def user_name_generator(name,firstlast = True):
username = name.lower().rsplit()
if firstlast:
username = username[0][0] + username[-1]
else:
username = username[-1] + username[0][0]
return username
This outputs rsmith if the parameter firstlast is set to True and outputs smithr if firstlast is set to False
if I understand your question correctly, you want to iterate through all the names of an excel sheet in the format 'firstletternamesurname'. This can be done with pandas, but I don't know if that's exactly what you want. With pandas there will be a final dataframe and you can export it to excel again. Try this:
import pandas as pd
df = pd.read_excel('name.xlsx')
for i in df:
df1 = df['name'].iloc[0] + df['surname'].iloc[0]
df2 = df1.split()[0]
print(df2.lower())

How to sub-string a list in Python

I have an assignment where I have a list with two names and I have to print the first name and then I have to print the last name.
names_list = ['Oluwaferanmi Fakolujo', 'Ajibola Fakolujo']
I have two names and then when I find the whitespace between them I have to print both the first name and the last name out of the list and put it into a variable.
I have tried to slice it but I don't understand it enough to use it. Here is an example:
substr = x[0:2]
This just brings both names instead of only substring it.
names_list = ['Oluwaferanmi Fakolujo', 'Ajibola Fakolujo']
for i in range(0, len(names_list)):
nf = names_list[i].split(' ')
name = nf[0]
family = nf[1]
print("Name is: {}, Family is: {}".format(name, family))
Output:
Name is: Oluwaferanmi, Family is: Fakolujo
Name is: Ajibola, Family is: Fakolujo
This will only work for Python 3.x
You can use the split() method and indexing for these kinds of problems.
Iterate through the list
split() the string
Store the values in a variable, so that we can index them
Display the values
names_list = ['Oluwaferanmi Fakolujo', 'Ajibola Fakolujo']
for i in names_list:
string = i.split(" ")
first_name = string[0]
last_name = string[1]
print(f"First Name: {first_name} Last Name: {last_name}")

simple way convert python string to quoted string

i'm new to python and i'm having a select statement like following help_category_id, name, what is the most effective way to convert this string to this:
'help_category_id', 'name'
i've currently done this, which works fine, but is there a nicer and more clean way to do the same:
test_string = 'help_category_id, name'
column_sort_list = []
if test_string is not None:
for col in test_string.split(','):
column = "'{column}'".format(column=col)
column_sort_list.append(column)
column_sort = ','.join(column_sort_list)
print(column_sort)
Simple one liner using looping constructs:
result = ", ".join(["'" + i + "'" for i.strip() in myString.split(",")])
What we are doing here is we are creating a list that contains all substrings of your original string, with the quotes added. Then, using join, we make that list into a comma delimited string.
Deconstructed, the looping construct looks like this:
resultList = []
for i in myString.split(","):
resultList.append("'" + i.strip() + "'")
Note the call to i.strip(), which removes extraneous spaces around each substring.
Note: You can use format syntax to make this code even cleaner:
New syntax:
result = ", ".join(["'{}'".format(i.strip()) for i in myString.split(",")])
Old syntax:
result = ", ".join(["'%s'" % i.strip() for i in myString.split(",")])
it can be achieved by this also.
','.join("'{}'".format(value) for value in map(lambda text: text.strip(), test_string.split(",")))

How to split a string on a character that occurs more than once inside the string

I am having a some logic issues attempting to parse a string into two fields. Name and Version. I have been splitting on "/" and it works very well for strings that have only one "/" in them. for example:
strString = someName/A
nameVer = strString .split('/')
name = nameVer[0]
ver = nameVer[1]
this returns name=someName and ver=A. Which is what i want. The problem is when i have more than one "/" in the string. Particularly this 3 cases:
Part ="someName//" #Expected output: name=someName ver=\
Part1="some/Name/A" #Expected output:name=some/Name ver=A
Part2="some/Name//" #Expected output:name=some/Name ver=/
Both the name and version can be or contain "/"'s. I have tried many things including keeping track of the indexes of the "/" and grabbing whats in between. In some cases I have also added brackets to the string ("[some/Name//]") so i can index the first and last char of the string. Any help with this is greatly appreciated. Thanks
Following some useful comments by BrenBarn and sr2222, I suggest the following solutions.
The OP should either
Make sure that the version string does not contain any '/' characters, and then use rsplit as suggested by sr2222
or
Choose a different delimiter for for the name-version division
A solution that ignores the last character (such that it can be assigned to the ver variable) would be
ind = Part[:-1].rindex('/')
name = Part[:ind+1]
ver = Part[ind+1:]
On the OPs inputs this produces the desired output.
If any instance of the separator might be doing the separating, there are too many choices. Take your last example, some/name//. Which of the three slashes is the
separator? The string can be parsed, in order, as ("some", "name//"),
as ("some/name", "/"), or as ("some/name/", "").
What to do? Let's say the version is necessarily non-empty (ruling out option 3),
and otherwise the name part should be maximal. If you like these rules,
here's a regexp that will do the job: r'^(.*)/(.+)$'. You can use it like this:
name, ver = re.match(r'^(.*)/(.+)$', "some/name/").groups()
Here's what it does:
>>> re.match(r'^(.*)/(.+)$', "name//").groups()
('name', '/')
>>> re.match(r'^(.*)/(.+)$', "some/name/a").groups()
('some/name', 'a')
>>> re.match(r'^(.*)/(.+)$', "some/name//").groups()
('some/name', '/')
>>> re.match(r'^(.*)/(.+)$', "some/name/").groups()
('some', 'name/')
In short, it splits on the last slash that has something after it (possibly a final slash). If you don't like this approach, you'll need to provide more detail on what you had in mind.
For the cases you've posted, this would work:
if part.endswith('//'):
name, ver = part[:-2], '/’
else:
name, ver = part.rsplit(’/’, 2)
Here is the code I made that handles just about every case. The only cases that it does not handle is when the name and version is ambiguous and you cannot tell if a "/" is apart of the name or ver. Thank you for everyone's input.
Part ="[0717_PFM1//]"
Part1="[0717_PFM1/A]" #generic case
Part2="[0717/_PFM1/A]"
Part3="[07/17/_PFM1//]" #Test case below
#Part3="[0717/_PFM1//B]" #Not working, ambigous: cant tell if the ending slash is part of name or ver
import re
lastCharIndex = Part3.index(']')
list1 =[]
counter = 0
numberOfSlashes = Part3.count("/")
if numberOfSlashes > 1:
nameVer = Part3.split("/")
name1, ver1 = re.match(r'^(.*)/(.+)$', Part3).groups()
if nameVer[2].strip("]") or ver1.strip("]") == "":
ver = "/"
else:
ver = nameVer[2].strip("]")
name = nameVer[0].strip('[')
if len(name1)>len(name):
name = name1
if len(ver1) > len(ver):
ver = ver1
name = name.rstrip("/")
else:
nameVer = Part3.split("/")
name, ver = nameVer[0], nameVer[1]
print "name",name.strip('['), "ver",ver.strip(']')

Pyparsing: How can I parse data and then edit a specific value in a .txt file?

my data is located in a .txt file (no, I can't change it to a different format) and it looks like this:
varaiablename = value
something = thisvalue
youget = the_idea
Here is my code so far (taken from the examples in Pyparsing):
from pyparsing import Word, alphas, alphanums, Literal, restOfLine, OneOrMore, \
empty, Suppress, replaceWith
input = open("text.txt", "r")
src = input.read()
# simple grammar to match #define's
ident = Word(alphas + alphanums + "_")
macroDef = ident.setResultsName("name") + "= " + ident.setResultsName("value") + Literal("#") + restOfLine.setResultsName("desc")
for t,s,e in macroDef.scanString(src):
print t.name,"=", t.value
So how can I tell my script to edit a specific value for a specific variable?
Example:
I want to change the value of variablename, from value to new_value.
So essentially variable = (the data we want to edit).
I probably should make it clear that I don't want to go directly into the file and change the value by changing value to new_value but I want to parse the data, find the variable and then give it a new value.
Even though you have already selected another answer, let me answer your original question, which was how to do this using pyparsing.
If you are trying to make selective changes in some body of text, then transformString is a better choice than scanString (although scanString or searchString are fine for validating your grammar expression by looking for matching text). transformString will apply token suppression or parse action modifications to your input string as it scans through the text looking for matches.
# alphas + alphanums is unnecessary, since alphanums includes all alphas
ident = Word(alphanums + "_")
# I find this shorthand form of setResultsName is a little more readable
macroDef = ident("name") + "=" + ident("value")
# define values to be updated, and their new values
valuesToUpdate = {
"variablename" : "new_value"
}
# define a parse action to apply value updates, and attach to macroDef
def updateSelectedDefinitions(tokens):
if tokens.name in valuesToUpdate:
newval = valuesToUpdate[tokens.name]
return "%s = %s" % (tokens.name, newval)
else:
raise ParseException("no update defined for this definition")
macroDef.setParseAction(updateSelectedDefinitions)
# now let transformString do all the work!
print macroDef.transformString(src)
Gives:
variablename = new_value
something = thisvalue
youget = the_idea
For this task you do not need to use special utility or module
What you need is reading lines and spliting them in list, so first index is left and second index is right side.
If you need these values later you might want to store them in dictionary.
Well here is simple way, for somebody new in python. Uncomment lines whit print to use it as debug.
f=open("conf.txt","r")
txt=f.read() #all text is in txt
f.close()
fwrite=open("modified.txt","w")
splitedlines = txt.splitlines():
#print splitedlines
for line in splitedlines:
#print line
conf = line.split('=')
#conf[0] is what it is on left and conf[1] is what it is on right
#print conf
if conf[0] == "youget":
#we get this
conf[1] = "the_super_idea" #the_idea is now the_super_idea
#join conf whit '=' and write
newline = '='.join(conf)
#print newline
fwrite.write(newline+"\n")
fwrite.close()
Actually, you should have a look at the config parser module
Which parses exactly your syntax (you need only to add [section] at the beginning).
If you insist on your implementation, you can create a dictionary :
dictt = {}
for t,s,e in macroDef.scanString(src):
dictt[t.name]= t.value
dictt[variable]=new_value
ConfigParser
import ConfigParser
config = ConfigParser.RawConfigParser()
config.read('example.txt')
variablename = config.get('variablename', 'float')
It'll yell at you if you don't have a [section] header, though, but it's ok, you can fake one.

Categories