number of digits in the exponent (string formatting) - python

It is easy to format the base of a number in python, but the exponent displays two digits by default. However, I would like to display only on digit (i.e. without the leading zero). See this example:
x=1.25e-5
s=f'{x:.2e}'
s will read '1.25e-04', however, I would like it to be '1.25e-4'.
How can I do this?

If you don't mind using external packages, this can be done using numpy.format_float_scientific
namely you can
import numpy as np
x = 1.25e-5
s = np.format_float_scientific(x,exp_digits=1)

Try this:
format(x).replace("E-0", "E-")
Actually this might be better
(x).ToString("0.#E+0");

Related

Regex python help for coordinate format

I'm working on a program that takes the input in a particular format:
example "(1,2)(2,3)(4,3)". They are coordinates and there can be infinitely many coordinates "(1,2)(2,3)(4,3)...(a,b)". I'm writing a function "checkFormat(str)" that returns true if the format is satisfied. I've tried writing a function without the use of regex but it proved too difficult. Need help with the regex expression.
Use ^ and $ to match the whole input. in between is one or more set of (...) filled with digits.
Assuming coordinates are integer and no extra space in between:
^((\((\d)+\,(\d)+)\))+$
if +/- is allowed and 0 has no sign and could not be extended (00 or 01 not accepted)
^(\(([-\+]?[1-9]\d*|0)\,(([-\+]?[1-9]\d*)|0)\))+$
If decimal numbers are included:
^(\(([-\+]?[1-9]\d*|0)([.]\d+)?\,(([-\+]?[1-9]\d*)|0)([.]\d+)?\))+$
To check if the input match or not:
import re
pattern=r'^(\(([-\+]?[1-9]\d*|0)([.]\d+)?\,(([-\+]?[1-9]\d*)|0)([.]\d+)?\))+$'
input='(0,2)(1,2)'
result=bool(re.match(pattern,input))

Python "zfill()" equivalent in OCaml

I'm a beginner and I have to learn Ocaml for scientific programming. I just have one question:
Is there an equivalent of Python's .zfill() method in Ocaml to make leading zeros appear in a string?
Strings in OCaml are immutable. That means you're not supposed to modify a string but to create a new one.
There is no zfill function in the standard library, but you can easily make one that way:
let zfill s width =
let to_fill = width - (String.length s) in
if to_fill <= 0 then s
else (String.make to_fill '0') ^ s
I don't think there's one.
You can do it easily with build-in functions when you're working with numbers. For instance, to print the number 142857 with leading 0's over 30 characters, use Printf.printf "%030d" 142857.
You can also make it work with strings if you're fine with using leading spaces instead of leading zeros. For instance, Printf.printf "%30s" "abcdefg".
Finally if you have to, you can define your own function if need be.
The way the first two options work is by using Printf, which is an extremely useful too you really should learn at some point. Here is its documentation for OCaml, but a lot of programming languages have a similar tool.
In %030d, we started from %d which is a placeholder that will be replaced by an integer (in our case, 142857). We fixed its minimum width to 30 (right-aligned by default) by adding 30 between the two characters: %30d. Finally, we added the option to make the leading characters zeros instead of spaces by adding a 0 after the percent sign.
%30s is just a placeholder for a right-aligned string of at least 30 characters (with leading spaces, because the options for leading zeros only works with numbers).
Now here's a zfill function if for some reason you can't use a well-chosen Printf format in your scenario:
let zfill n s =
let length = Bytes.length s in
if n <= length then
s
else
let result = Bytes.make n '0' in
Bytes.blit s 0 result (n-length) length;
result
;;
Notice that if performance is an issue (though it probably isn't), this should perform faster than the solution of creating a string of zeros and then concatenating it with s, as while blit is done "in-place", string concatenation is not, so a temporary string of zeros has to be created. In most scenarios, it shouldn't matter all that much and you can use either option.

Display a number in scientific notation with specific digits

i want to display numbers in scientific notation:
-407.45833
So far i used this:
i = '%E' % Decimal(i)
result:
-4.074583E+02
now my question: how can i add one more digit so it looks like this:?
-4.074583E+002
I know i should find my answer in the tables from Python string formatting to select the proper format layout, but i cant find it. Can someone tell me the result and where to find it please?
There's unfortunately not any direct way using string formatting to have three digits following the +. A easy method to replace it is to use this since what we know is that is exponential forms are all stored as strings, so all the string methods will work on it.
I wrote a little function that takes a regular scientific notation and returns a formatted notation with three digits after the +:
from decimal import Decimal
def pretty(notation, n):
if '+' in notation:
return "+".join([notation.split('+')[0],notation.split('+')[1].zfill(n)])
return "-".join([notation.split('-')[0],notation.split('-')[1].zfill(n)])
i = '%E' % Decimal(-407.45833)
print(pretty(i,3)) # leave three digits

How do I fix this OverflowError?

I keep getting a "OverflowError: math range error". No matter what I input, the result is the same. I'm running Python 3.3, and it's finding the problem at the last line. How do I fix this? (Also, I don't want to hear anything about my overuse of parentheses. It is my preference for there to be this many.):
import math
a=float(input('a=?'))
b=float(input('b=?'))
c=float(input('c=?'))
d=float(input('d=?'))
critical_point_n=((-2*b)-math.sqrt(abs((4*(math.pow(b, 2)))-(12*a*c))))/(6*a)
first_root=critical_point_n-1
if first_root==0 and c==0:
first_root+=(-0.01)
for x in range(10):
first_root=first_root-((a*(math.pow(first_root, 3)))+(b*(math.pow(first_root, 2))+(c*first_root)+d)/(3*(a*(math.pow(first_root, 2))))+(2*(b*first_root))+c)
I know you don't want to hear about your excessive use of parenthesis, but the problem is that you have the parenthesis in the wrong places. With the sheer number of parenthesis you used, it took a while to find the problem.
I think the following code is much cleaner, easier to debug, and vastly easier to maintain in the future. I also included what I think is the corrected version of your one-liner.
import math
a=float(input('a=?'))
b=float(input('b=?'))
c=float(input('c=?'))
d=float(input('d=?'))
critical_point_n=((-2*b)-math.sqrt(abs((4*(math.pow(b, 2)))-(12*a*c))))/(6*a)
first_root=critical_point_n-1
if first_root==0 and c==0:
first_root+=(-0.01)
for x in range(10):
f = a*first_root**3 + b*first_root**2 + c*first_root + d
fp = 3*a*first_root**2 + 2*b*first_root + c
first_root = first_root - (f/fp)
#first_root=first_root-(((a*(math.pow(first_root, 3)))+(b*(math.pow(first_root, 2))+(c*first_root)+d)))/((3*(a*(math.pow(first_root, 2))))+(2*(b*first_root))+c)
print(first_root)
You are overflowing the internal representation of floats. Use sys.float_info to check your system's limits for floating point numbers. http://docs.python.org/3.3/library/sys.html#sys.float_info
I recommend trying out your operations by "hand" on wolframalpha to see the magnitude of the actual values. http://www.wolframalpha.com/
The math range of functions work on doubles... so you're out of range for that - re-write as normal Python floats which will scale as needs be, or look at using decimal.Decimal which also has sqrt, power etc.. functions: http://docs.python.org/2/library/decimal.html

How do generate random numbers, while avoiding numbers already used

How do i generate random numbers but have the numbers avoid numbers already used.
I have a TXT file with thousands of sets of numbers and i need to generate a series of random numbers while avoiding these.
IE, TXT - 0102030405
my random number needs to avoid this number.
on a side note, how can i split up the TXT 10 digit number into 5, two digit numbers?
then how can i generate random numbers based off of that.
You could load up all previously found random numbers into a dictionary, then just check whether new_random in dictionary, and if it is try a new random number.
For the second party, say your ten digit number is stored in variable ten_digits.
ten_digits = '1234567890'
you can break this up into 5 two digit numbers by doing
[x + y for x, y in zip(ten_digits[::2], ten_digits[1::2]
>>> ['12', '34', '56', '78', '90']
If you need to maintain the file (which I think you do, in order to add new numbers), I would suggest you to "forget" using a plain text file and use SQLite or any other embedded DB that is backed up in a file, as you probably don't want to load all the numbers in memory.
The "feature" (or better said, data structure) you want from SQLite is a B-Tree, so you can retrieve the numbers fast. I'm saying this, because you could also try to find a library that implements B-Trees, and then you wouldn't need SQLite.
Are you using the numbers as IDs? You should probably look into using a hash table.
http://en.wikipedia.org/wiki/Hash_table
I'm not terribly familiar with Python but I'm sure there is a substring function you can give it (as arguments) an index to start the substring and the number of characters to copy.
If you your list is relatively small you could load it into a set and check against that:
random_number not in number_set
To split the number you could use slices:
s='0102030405'
n=2
result = [s[i:i+n] for i in range(0, len(s), n)]

Categories