Getting PyEphem to return angles with sign - python

How do I get PyEphem to give angles with sign and a zero padded to degrees. Currently it returns 2:46:32.8 but I want it in the form +02:46:32.8.
Now, I could define a function to return it in that form, but I was wondering if there was a simpler way.

No, the underlying C code inside of libastro does not support leading plus signs or leading zeros. You will have to write a little Python function of your own to add them.

Related

Is there a way to change a spinbox's groupSeparator symbol?

I am looking for a way to force the groupSeparator symbol of a doublespinbox.
For context, one of my programs uses an numerical input (doublespinbox) + unit choices (radio buttons) to form a number. It looks roughly like this:
voltage [ 5 ] o V
o mV
o µV
I use a group separator to make reading easier. On a French machine I get a satisfying display, where for example 1 thousand and 1 look like so: 1 000 or 1,000. On an English machine, I get 1,000 and 1.000 which can be easily confused. How could I force the group separator to be always a space?
Alternatively, I believe that a solution could be to force the locale of the program as answered here but I'm always interested in seeing if custom solutions are possible. Otherwise, I'll stick to
self.setLocale(QtCore.QLocale(QtCore.QLocale.French))
Another possibility is to reimplement your own subclass for the spinbox and override the textFromValue() function:
class SpaceSeparatorSpin(QtWidgets.QDoubleSpinBox):
def textFromValue(self, value):
text = self.locale().toString(float(value), 'f', self.decimals())
return text.replace(self.locale().groupSeparator(), ' ')
In this way, we use the current (default) locale to transform the value to a string and then return the string with the separator replaced with the space.
There are some issues with both approaches, though.
Using a custom locale for a single widget class can result in unexpected behavior when using copy&paste functions: if the user lives in a country that uses the point for the decimals, a simple "50.2" value that might be taken from another source will not be pasted, as the validator will not recognize that string as valid (for the French locale, it should be "50,2").
Using the textFromValue override has the opposite problem if the user wants to copy from a subclassed spinbox to another, as the space separator will make the validator ignore the string when the spinbox calls valueFromText().
To avoid all that, you could override the validate() function: if the base implementation returns a valid or intermediate value, return it, otherwise validate it on your own being careful about the current locale and the possibility of the "double input possibilities" (with or without spaces, inverted points/commas for decimals and group separators); note that while pasting a "space-separated" value on a locale that uses them works, QAbstractSpinBox doesn't accept spaces when typing.
Besides all that, keep in mind that using "de-localized" decimal points and separator is not a good thing. While it might seem fine for you, user with other types of punctuations will probably find it very annoying, especially for people that are used to the numeric pad: usually, the decimal point key of the pad is configured with that of the system locale, so users that have a locale that uses the point for decimals won't be able to type decimals from the pad, forcing them to move their hand away from it to type the comma.

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.

Regular expression for validation of inequality inputted by user

I searched for an answer but I couldn't find a clear one. Please, bear with me as I'm kind of a noob in regex, and this is my first question too. I'm using Python 3, but will also be needing this for Javascript too.
What I'm trying to do is validate an input by the user. The input is an inequality (spaces removed), and the variables are named by the user and given beforehand.
For example, let's say I have this inequality:
x+y+6p<=z+1
The variables x, y, p, z will be given. The problem now if the inequality is like this:
xp+yp+6p<=z+1
The given variables are xp, yp, p, and z.
I'm trying to write a regular expression to match any inequality with such a format, given no spaces in the inequality. I cannot figure out how to check for alternative strings. For example I wrote the following expression:
^([\+\-]?[0-9]*([xpypz]|[0-9]+))+[<>]=([\+\-]?[0-9]*([xpypz]|[0-9]+))+$
I know this is completely wrong and that's not how the parentheses are used, but I don't have a feasible expression and I wanted to show you what I want to achieve. Now I need to know three things (at least, I hope) to fix it:
How to check specifically for xp, and yp as they are literally instead of all characters in the set xypz?
How to make 0-9 after xpypz work as [0-9]+? Meaning that any number can occur instead of a variable?
How can I repeat make the whole group repeated
I'm trying to write this expression to check if the user is adding undeclared variables. I believe this can be done differently without using regex, but it would be nice to do it in a single line. Can you please help me figure out those three point? Thanks.
try this pattern
(^(?=.)(?:(?:[+-]?\d*(?:xp|yp|p|z)*)+)[<>]=(?=.)(?:(?:[+-]?\d*(?:xp|yp|p|z)*)+)$)
Demo
[0-9]*(xp|yp|p|z)*([+-][0-9]*(xp|yp|p|z)*)*(<|>|<=|>=)[0-9]*(xp|yp|p|z)*([+-][0-9]*(xp|yp|p|z)*)*
This is ugly and won't catch mistakes like 1++x<p nor does it allow for other functions like sin or exponents. It matches on xp+yp+6p<=z+1 but does not on xp+yp+6x<=z+1 if xp, yp, p, and z are the variables given.
As Greg Ball mentioned, though, the best thing would be to use parsing if possible. Then you could catch more syntax errors besides using wring variables and you could do so more reliably.

Extracting a Floating point exponential formatted number from a text file

I'm trying to extract a floating point exponential number from a number of .txt files that is searched for using a phrase and then extracted. For example I have a .txt file that looks like this.
FEA Results:
Tip rotation (deg) =, 7.107927E-18
Tip displacement =, 3.997556E-07
And I'm extracting the tip rotation data using the following script:
regexp = re.compile(r'Tip rotation .*?([0-9.-]+)')
with open(fileName) as f:
for line in f:
match = regexp.match(line)
if match:
rotations.append(float((match.group(1))))
The problem is it only returns the first part of the floating point exponential (i.e. 7.107927 instead of 7.107927E-18). Any idea on how I could correct it?
Your regex has this:
([0-9.-]+)
It's missing the E - add that in the brackets (at the front or the back, doesn't matter). Also, you may need to move the minus sign to the front, so it isn't interpreted as a range. Like this:
([-0-9.E]+)
Your regular expression doesn't allow for E-18. Specifically, E isn't mentioned.
See this question for better regexps: How to detect a floating point number using a regular expression

Python- stuck trying to create a "free hand" calculator

I'm trying to create a calculator program in which the user can type an equation and get an answer. I don't want the full code for this, I just need help with a specific part.
The approach I am trying to take is to have the user input the equation as a string (raw_input) and then I am trying to convert the numbers from their input to integers. After that I need to know how I can get the operands to do what I want them to do depending on which operand the user uses and where it is in the equation.
What are some methods I might use to accomplish this task?
Here is basically what I have right now:
equation_number = raw_input("\nEnter your equation now: ")
[int(d) for d in equation_number if d.isdigit()]
Those lines are just for collecting input and attempting to convert the numbers into integers. Unfortunately, it does not seem to be working very well and .isdigit will only work for positive numbers anyway.
Edit- aong152 mentioned recursive parsing, which I looked into, and it appears to have desirable results:
http://blog.erezsh.com/how-to-write-a-calculator-in-70-python-lines-by-writing-a-recursive-descent-parser/
However, I do not understand the code that the author of this post is using, could anyone familiarize me with the basics of recursive parsing?
The type of program you are trying to make is probably more complicated than you think
The first step would be separating the string into each argument.
Let's say that the user inputs:
1+2.0+3+4
Before you can even convert to ints, you are going to need to split the string up into its components:
1
+
2.0
+
3
+
4
This will require a recursive parser, which (seeing as you are new to python) maybe be a bit of a hurdle.
Assuming that you now have each part seperately as strings,
float("2.0") = 2.0
int(2.0) = 2
Here is a helper function
def num (s):
try:
return int(s)
except exceptions.ValueError:
return int(float(s))
instead of raw_input just use input because raw_input returns a string and input returns ints
This is a very simple calculator:
def calculate():
x = input("Equation: ")
print x
while True:
calculate()
the function takes the input and prints it then the while loop executes it again
im not sure if this is what you want but here you go and also you should make a way to end the loop
After using raw_input() you can use eval() on the result to compute the value of this string. eval() evaluates any valid Python expression and returns the outcome.
But I think this is not to your liking. You probably want to do more by yourself.
So I think you should have a look at the re module to split the input using regular expressions into tokens (sth like numbers and operators). After this you should write a parser which gets the token stream as input. You should decide whether this parser shall just return the computed value (e. g. a number) or maybe an abstract syntax tree, i. e. a data structure which represents the expression in an object-oriented (instead of character-oriented) way. Such an Absy could then be evaluated to get the final result.
Are you familiar with regular expressions? If not, it's probably a good idea to first learn about them. They are the weak, non-recursive cousin of parsing. Don't go deep, just understand the building blocks — A then B, A many times, A or B.
The blog post you found is hard because it implements the parsing by hand. It's using recursive descent, which is the only way to write a parser by hand and keep your sanity, but it's still tricky.
What people do most of the time is only write a high level grammar and use a library (or code generator) to do the hard work of parsing.
Indeed he had an earlier post where he uses a library:
http://blog.erezsh.com/how-to-write-a-calculator-in-50-python-lines-without-eval/
At least the beginning should be very easy. Things to pay attention to:
How precedence arises from the structure of the grammar — add consists of muls, not vice versa.
The moment he adds a rule for parentheses:
atom: neg | number | '(' add ')';
This is where it really becomes recursive!
6-2-1 should parse as (6-2)-1, not 6-(2-1). He doesn't discuss it, but if you look
carefully, it also arises from the structure of the grammar. Don't waste tome on this; just know for future reference that this is called associativity.
The result of parsing is a tree. You can then compute its value in a bottom-up manner.
In the "Calculating!" chapter he does that, but the in a sort of magic way.
Don't worry about that.
To build a calculator yourself, I suggest you strip the problem as much as possible.
Recognizing where numbers end etc. is a bit messy. It could be part of the grammar, or done by a separate pass called lexer or tokenizer.
I suggest you skip it — require the user to type spaces around all operators and parens. Or just assume you're already given a list of the form [2.0, "*", "(", 3.0, "+", -1.0, ")"].
Start with a trivial parser(tokens) function that only handles 3-element expressions — [number, op, number].
Return a single number, the result of the computation. (I previously said parsers output a tree which is processed later. Don't worry about that, returning a number is simpler.)
Write a function that expects either a number or parentheses — in the later case it calls parser().
>>> number_or_expr([1.0, "rest..."])
(1.0, ["rest..."])
>>> number_or_expr(["(", 2.0, "+", 2.0, ")", "rest..."])
(4.0, ["rest..."])
Note that I'm now returning a second value - the remaining part of the input. Change parser() to also use this convention.
Now Rewrite parser() to call number_or_expr() instead of directly assuming tokens[0] and tokens[2] are numbers.
Viola! You now have a (mutually) recursive calculator that can compute anything — it just has to be written in verbose style with parens around everything.
Now stop and admire your code, for at least a day :-) It's still simple but has the essential recursive nature of parsing. And the code structure reflects the grammar 1:1 (which is the nice property of recursive descent. You don't want to know how the other algorithms look).
From here there many improvements possible — support 2+2+2, allow (1), precedence... — but there are 2 ways to go about it:
Improve your code step by step. You'll have to refactor a lot.
Stop working hard and use a parsing library, e.g. pyparsing.
This will allow you to experiment with grammar changes faster.

Categories