Using f String to insert characters or symbols # - python

I have two variables that store two numbers in total.
I want to combine those numbers and separate them with a comma. I read that I can use {variablename:+} to insert a plus or spaces or a zero but the comma doesn't work.
x = 42
y = 73
print(f'the number is {x:}{y:,}')
here is my weird solution, im adding a + and then replacing the + with a comma. Is there a more direct way?
x = 42
y = 73
print(f'the number is {x:}{y:+}'.replace("+", ","))
Lets say I have names and domain names and I want to build a list of email addresses. So I want to fuse the two names with an # symbol in the middel and a .com at the end.
Thats just one example I can think off the top of my head.
x = "John"
y = "gmail"
z = ".com"
print(f'the email is {x}{y:+}{z}'.replace(",", "#"))
results in:
print(f'the email is {x}{y:+}{z}'.replace(",", "#"))
ValueError: Sign not allowed in string format specifier

You are over-complicating things.
Since only what's between { and } is going to be evaluated, you can simply do
print(f'the number is {x},{y}') for the first example, and
print(f'the email is {x}#{y}{z}') for the second.

When you put something into "{}" inside f-formatting, it's actually being evaluated. So, everything which shouldn't put it outside the "{}".
Some Examples:
x = 42
y = 73
print(f'Numbers are: {x}, {y}') # will print: 'Numbers are: 42, 73'
print(f'Sum of numbers: {x+y}') # will print: 'Sum of numbers: 115'
You can even do something like:
def compose_email(user_name, domain):
return f'{user_name}#{domain}'
user_name = 'user'
domain = 'gmail.com'
print(f'email is: {compose_email(user_name, domain)}')
>>email is: user#gmail.com
For more examples see:
Nested f-strings

Related

How to replace string and exclude certain changing integers?

I am trying to replace
'AMAT_0000006951_10Q_20200726_Filing Section: Risk'
with:
'AMAT 10Q Filing Section: Risk'
However, everything up until Filing Section: Risk will be constantly changing, except for positioning. I just want to pull the characters from position 0 to 5 and from 15 through 19.
df['section'] = df['section'].str.replace(
I'd like to manipulate this but not sure how?
Any help is much appreciated!
Given your series as s
s.str.slice(0, 5) + s.str.slice(15, 19) # if substring-ing
s.str.replace(r'\d{5}', '') # for a 5-length digit string
You may need to adjust your numbers to index properly. If that doesn't work, you probably want to use a regular expression to get rid of some length of numbers (as above, with the example of 5).
Or in a single line to produce the final output you have above:
s.str.replace(r'\d{10}_|\d{8}_', '').str.replace('_', ' ')
Though, it might not be wise to replace the underscores. Instead, if they change, explode the data into various columns which can be worked on separately.
If you want to replace a fix length/position of chars, use str.slice_replace to replace
df['section'] = df['section'].str.slice_replace(6, 14, ' ')
Other people would probably use regex to replace pieces in your string. However, I would:
Split the string
append the piece if it isn't a number
Join the remaining data
Like so:
s = 'AMAT_0000006951_10Q_20200726_Filing Section: Risk'
n = []
for i in s.split('_'):
try:
i = int(i)
except ValueError:
n.append(i)
print(' '.join(n))
AMAT 10Q Filing Section: Risk
Edit:
Re-reading your question, if you are just looking to substring:
Grabbing the first 5 characters:
s = 'AMAT_0000006951_10Q_20200726_Filing Section: Risk'
print(s[:4]) # print index 0 to 4 == first 5
print(s[15:19]) # print index 15 to 19
print(s[15:]) # print index 15 to the end.
If you would like to just replace pieces:
print(s.replace('_', ' '))
you could throw this in one line as well:
print((s[:4] + s[15:19] + s[28:]).replace('_', ' '))
'AMAT 10Q Filing Section: Risk'

python and join confusion

Problem: Write a function that will return a string of country codes from an argument that is a string of prices (containing dollar amounts following the country codes). Your function will take as an argument a string of prices like the following: "US$40, AU$89, JP$200". In this example, the function would return the string "US, AU, JP".
Hint: You may want to break the original string into a list, manipulate the individual elements, then make it into a string again.
Input:
def get_country_codes(prices):
values = ""
price_codes = prices.split(',')
for price_code in price_codes:
values = value + price_code.strip()[0:2])
return values
list1 = [ , ]
print(get_country_codes("NZ$300, KR$1200, DK$5").join(list1))
Since some existing currencies have a three letters symbol, such as CAD, we have to expect an unknown number of characters before any amount.
def get_countries(s):
countries = [c.split('$')[0] for c in s.split(',')]
return ','.join(countries)
s = "US$40, AU$89, JP$200, CAD$15"
print(get_countries(s))
Output
US, AU, JP, CAD
Alternatively, you can use re to simply remove anything following the country code in your string.
import re
s = "US$40, AU$89, JP$200, CAD$15"
countries = re.sub('\W\d+', '', s)
print(countries)
Try this:
codes="NZ$300, KR$1200, DK$5"
get_country_codes=lambda c: ', '.join(e[0:2] for e in c.split(", "))
get_country_codes(codes)

Using raw input and doing calculations in python

So for part of the assignment I am doing, I ask the user their address (including street name) and minus it from 68.
so far I have:
streetName = raw_input("Please enter your address: ")
say the user enters there address as 668 Rickman Street, I am supposed to take the 668 and minus it from 68 and what would be printed is
"your secret code is -600"
-600 being obviously the calculation of 68-668
However I do not know how to take the 668 out of the raw input and put it into the calculation.
You can check and try to cast each splitted string if you are sure you have spaces between your number and street name
streetName = raw_input("Please enter your address: ")
names = streetName.split(' ')
secret_code = -1
for name in names :
try :
secret_code = 68 - int(name)
except ValueError :
continue
# Thanks to Jon Clements
if secret_code > 68 :
print 'something went wrong , check your address'
else
print secret_code
You can go through streetName using a for loop and stop wherever you find the first space, store the index and extract a substring starting in 0 to the index calculated, then parse it to integer.
Example Code:
stringVar = "123 Hello world"
subStringVar = a[0:3]
stringParsed = int(subStringVar)
So now stringParsed is 123, then just do a simple operation 68 - stringParsed.
you can split the input string on whitespace delimiter:
>>> int("668 Rickman Street".split()[0])
668
I think the first thing to do is to understand what data structures you will use
to get to your final answer. Look out for examples on string and list comprehension.
Lets say street_name is a string. If the address occurs in the same index in street_name then you can exit the loop once you have accessed the first word or encountered the first blank space after 686.
Or you can convert the string into a list.
street_name_lst = street_name.split()
where street_name_lst => ['668', 'Rickman', 'Street']
Now you just access the first element using first index.
address = street_name_lst[0]
Now str_address => '686' , but this is in string(incompatible type to do any processing with an Integer type for your case), so lets convert String address
to Integer type.
int_add = int(str_address)
Now you have int_add => 686 and now you can do further computation on it.
Remember data structures and type systems in any language are important.
Also look into PEP8 standard to check for good convention on naming your variables.
https://www.python.org/dev/peps/pep-0008/#id38
It might be helpful to install ipython. check http://ipython.org/

MySQL and Python: Convert string value to int, to float or what?

I have a string that contains salary information in the following way:
salaryMixed = "£25,000 - £30,000"
Sometimes it will look like this:
salaryMixed = "EUR25,000 - EUR30,000"
And others times like this:
salaryMixed = "£37.50 - £50.00"
What I want to do is to remove all characters but the numeric values and then split the two values so as to place them into their own respective variables that reflect low banding and high banding. So far I have:
if salaryMixed.find('£')!=-1: # found £ char
salaryMixed = salaryMixed.replace("£", "")
if salaryMixed.find('-')!=-1: # found hyphen
salaryMixed = salaryMixed.replace("-", "")
if salaryMixed.find(',')!=-1: # found comma
salaryMixed = salaryMixed.replace(",", "")
if salaryMixed.find('EUR')!=-1: # found EUR
salaryMixed = salaryMixed.replace("EUR", "")
salaryMixed = re.sub('\s{2,}', ' ', salaryMixed) # to remove multiple space
if len(salaryList) == 1:
salaryLow = map(int, 0) in salaryList
salaryHigh = 00000
else:
salaryLow = int(salaryList.index(1))
salaryHigh = int(salaryList.index(2))
But I am stumped with how to split the two values up, and also how to handle the decimal point when salaryMixed isn't an annual salary but rather per hour as in the case of salaryMixed = "£37.50 - £50.00" because isn't that a float?
I am wanting to store this information in a MySQL DB later on in the code but I have described the table as:
CREATE TABLE jobs(
job_id INT NOT NULL AUTO_INCREMENT,
job_title VARCHAR(300) NOT NULL,
job_salary_low INT(25),
job_salary_high INT(25),
PRIMARY KEY ( job_id )
);
What is the best approach here? Thanks.
This is a good case for a regular expression from the python re module. And you'll probably want to upcast the hourly rates to annual (assuming you have a consistent average hourly
import re
def salary_band(val):
currency = 'EUR' if 'EUR' in val else 'GBP'
numbers = re.findall("[0-9.\,]*", val) # this will have a bunch of empty entries and two numbers
numbers = [i.replace(",","") for i in numbers if i] # filter out empty strings, remove commas
numbers = map(float, numbers) # convert to floats
annual = lambda p: int(p) if p > 2000 else int( p * 1800) # your number here...
return currency, map(annual, numbers)
print salary_band ( "gbp37.50 - gbp50.00")
print salary_band ( "EUR25,000 - EUR30,000")
>> ('GBP', [75000, 100000])
>> ('EUR', [25000, 30000])
Here i'm returning the currency type and the high/low numbers as a tuple - you can unpack it easily into your table
What I want to do is to remove all characters but the numeric values
and then split the two values so as to place them into their own
respective variables that reflect low banding and high banding. So far
I have:
Ok taking this one step at a time. Remove all the characters but the numeric values (Better keep spaces and periods too)
>>> testcases = ["£25,000 - £30,000", "EUR25,000 - EUR30,000", "£37.50 - £50.00"]
>>> res = [''.join(x for x in tc if x.isdigit() or x.isspace() or x == '.') for tc in testcases]
>>> res
['25000 30000', '25000 30000', '37.50 50.00']
ok, now split them
>>> res = [x.split() for x in res]
>>> res
[['25000', '30000'], ['25000', '30000'], ['37.50', '50.00']]
Convert to floats (Decimal might be better)
>>> res = [[float(j) for j in i] for i in res]>>> res
[[25000.0, 30000.0], [25000.0, 30000.0], [37.5, 50.0]]
Put in separate variables
>>> for low, high in res:
... print (low, high)
...
25000.0 30000.0
25000.0 30000.0
37.5 50.0
regex as suggested by #Patashu is the easy/lazy way to do it though
for storing the values in db, you can use MySQLdb library in python.It's easy to use and will store al your data to database. Here check it out.
You can install it by apt-get install python-mysqldb

Format an un-decorated phone number in django?

I've got a DB chock full o' phone numbers as strings, they're all formatted like 1112223333, I'd like to display it as 111-222-3333 in my django template
I know I can do
n = contacts.objects.get(name=name)
n.phone = n.phone[:3] + '-' + n.phone[3:6] + '-' + n.phone[6:]
but is there a better / more pythonic way?
It may be overkill for your use case if all your numbers are formatted the same way, but you might consider using the phonenumbers module. It would allow you to add functionality (e.g. international phone numbers, different formatting, etc) very easily.
You can parse your numbers like this:
>>> import phonenumbers
>>> parsed_number = phonenumbers.parse('1112223333', 'US')
>>> parsed_number
PhoneNumber(country_code=1, national_number=1112223333L, extension=None, italian_leading_zero=False, country_code_source=None, preferred_domestic_carrier_code=None)
Then, to format it the way you want, you could do this:
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumber())
u'111-222-3333'
Note that you could easily use other formats:
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumberFormat.NATIONAL)
u'(111) 222-3333'
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
u'+1 111-222-3333'
>>> phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumberFormat.E164)
u'+11112223333'
Just one other solution:
n.phone = "%c%c%c-%c%c%c-%c%c%c%c" % tuple(map(ord, n.phone))
or
n.phone = "%s%s%s-%s%s%s-%s%s%s%s" % tuple(n.phone)
This is quite a bit belated, but I figured I'd post my solution anyway. It's super simple and takes advantage of creating your own template tags (for use throughout your project). The other part of this is using the parenthesis around the area code.
from django import template
register = template.Library()
def phonenumber(value):
phone = '(%s) %s - %s' %(value[0:3],value[3:6],value[6:10])
return phone
register.filter('phonenumber', phonenumber)
For the rest of your project, all you need to do is {{ var|phonenumber }}
Since we're speaking Pythonic :), it's a good habit to always use join instead of addition (+) to join strings:
phone = n.phone
n.phone = '-'.join((phone[:3],phone[3:6],phone[6:]))
def formatPhone(phone):
formatted = ''
i = 0
# clean phone. skip not digits
phone = ''.join(x for x in phone if x.isdigit())
# set pattern
if len(phone) > 10:
pattern = 'X (XXX) XXX-XX-XX'
else:
pattern = 'XXX-XXX-XX-XX'
# reverse
phone = phone[::-1]
pattern = pattern[::-1]
# scan pattern
for p in pattern:
if i >= len(phone):
break
# skip non X
if p != 'X':
formatted += p
continue
# add phone digit
formatted += phone[i]
i += 1
# reverse again
formatted = formatted[::-1]
return formatted
print formatPhone('+7-111-222-33-44')
7 (111) 222-33-44
print formatPhone('222-33-44')
222-33-44
print formatPhone('23344')
2-33-44

Categories

Resources