Problem calculating area of a rectangle using decimal values in python3 - area

This program is written to find area of a rectangle.
l = float(input("Lenght of rectangle:"))
b = float(input("Breadht of rectangle:"))
area = l*b
print ("Area of square = l*b")
print (" =",l,"*",b)
print (" =",area)
The input length is 12.4 and the input breadth is 13 So the answer must be 161.2
however the answer coming is 161.20000000000002 What's going wrong?

Check out https://medium.com/code-85/how-to-stop-floating-point-arithmetic-errors-in-python-a98d3a63ccc8.
"This happens because decimal values are actually stored as a formula and do not have an exact representation."

Use the following program instead of the above one
l = float(input("Lenght of rectangle:"))
b = float(input("Breadht of rectangle:"))
area = (l*b)
a_float = "{:.2f}".format(area)
print ("Area of square = l*b")
print (" =",l,"*",b)
print (" =",area)
Here, we have format the program so that we only get two digits after the decimal. in this way the outcome will be similar to what we exactly wanted.
For more information, visit
https://www.kite.com/python/answers/how-to-print-a-float-with-two-decimal-places-in-python#:~:text=Use%20str.,number%20with%20two%20decimal%20places.
reference:- www.kite.com

Related

Fast string splitting in MATLAB

I've been using MATLAB to read through a bunch of output files and have noticed that it was reading the files fairly slowly in comparison to a reader that I wrote in Python for the same files (on the order of 120s for MATLAB, 4s for Python on the same set). The files have a combination of letters and numbers, where the numbers I actually want each have a unique string on the same line, but there is no real pattern to the rest of the file. Is there a faster way to read in non-uniformly formatted text files in MATLAB?
I tried using the code profiler in MATLAB to see what takes the most time, and it seemed to be the strfind and strsplit functions. Deeper down, the strfun\private\strescape seems to be the culprit which takes up around 50% of the time, which is called by strsplit function.
I am currently using a combination of strfind and strsplit in order to search through a file for 5 specific strings, then convert the string after it into a double.
lots of text before this
#### unique identifying text here
lots of text before this
sometext X = #####
Y = #####
Z = #####
more text = ######
I am iterating through the file with approximately the following code, repeated for each number that is being found.
fid=fopen(filename)
tline=fgets(fid)
while ischar(tline)
if ~isempty(strfind(tline('X =')))
tempstring=strsplit(tline(13:length(tline)),' ');
result=str2double(char(tempstring(2)));
end
tline=fgets(fid);
end
I'm guessing this will be a bit faster, but maybe not by much.
s = fileread('texto');
[X,s] = strtok(strsplit(s, "X = "){2}); X = str2num(X);
[Y,s] = strtok(strsplit(s, "Y = "){2}); Y = str2num(Y);
[Z,s] = strtok(strsplit(s, "Z = "){2}); Z = str2num(Z);
Obviously this is highly specific to your text example. You haven't given me any more info on how the variables might change etc so presumably you'll have to implement try/catch blocks if files are not consistent etc.
PS. This is octave syntax which allows chaining operations. For matlab, split them into separate operations as appropriate.
EDIT: ach, nevermind, here's the matlab compatible one too. :)
s = fileread('texto');
C = strsplit(s, 'X = '); [X,s] = strtok(C{2}); X = str2num(X);
C = strsplit(s, 'Y = '); [Y,s] = strtok(C{2}); Y = str2num(Y);
C = strsplit(s, 'Z = '); [Z,s] = strtok(C{2}); Z = str2num(Z);

How to find a frequent character in a string written in pseudocode. Thanks

Most Frequent Character
Design a program that prompts the user to enter a string, and displays the character that appears most frequently in the string.
It is a homework question, but my teacher wasn't helpful and its driving me crazy i can't figure this out.
Thank You in advance.
This is what i have so far!
Declare String str
Declare Integer maxChar
Declare Integer index
Set maxChar = 0
Display “Enter anything you want.”
Input str
For index = 0 To length(str) – 1
If str[index] =
And now im stuck. I dont think its right and i dont know where to go with it!
It seems to me that the way you want to do it is:
"Go through every character in the string and remember the character we've seen most times".
However, that won't work. If we only remember the count for a single character, like "the character we've seen most times is 'a' with 5 occurrences", we can't know if perhaps the character in the 2nd place doesn't jump ahead.
So, what you have to do is this:
Go through every character of the string.
For every character, increase the occurrence count for that character. Yes, you have to save this count for every single character you encounter. Simple variables like string or int are not going to be enough here.
When you're done, you're left with a bunch of data looking like "a"=5, "b"=2, "e"=7,... you have to go though that and find the highest number (I'm sure you can find examples for finding the highest number in a sequence), then return the letter which this corresponds to.
Not a complete answer, I know, but that's all I'm going to say.
If you're stuck, I suggest getting a pen and a piece of paper and trying to calculate it manually. Try to think - how would you do it without a computer? If your answer is "look and see", what if the text is 10 pages? I know it can be pretty confusing, but the point of all this is to get you used to a different way of thinking. If you figure this one out, the next time will be easier because the basic principles are always the same.
This is the code I have created to count all occurences in a string.
String abc = "aabcabccc";
char[] x = abc.toCharArray();
String _array = "";
for(int i = 0; i < x.length; i++) //copy distinct data to a new string
{
if(_array.indexOf(x[i]) == -1)
_array = _array+x[i];
}
char[] y = _array.toCharArray();
int[] count1 = new int[_array.length()];
for(int j = 0; j<x.length;j++) //count occurences
{
count1[new String(String.valueOf(y)).indexOf(x[j])]++;
}
for(int i = 0; i<y.length;i++) //display
{
System.out.println(y[i] + " = " + count1[i]);
}

How do I convert a spreadsheet "letternamed" column coordinate to an integer?

In spreadsheets I have cells named like "F14", "BE5" or "ALL1". I have the first part, the column coordinate, in a variable and I want to convert it to a 0-based integer column index.
How do I do it, preferably in an elegant way, in Ruby?
I can do it using a brute-force method: I can imagine loopping through all letters, converting them to ASCII and adding to a result, but I feel there should be something more elegant/straightforward.
Edit: Example: To simplify I do only speak about the column coordinate (letters). Therefore in the first case (F14) I have "F" as the input and I expect the result to be 5. In the second case I have "BE" as input and I expect getting 56, for "ALL" I want to get 999.
Not sure if this is any clearer than the code you already have, but it does have the advantage of handling an arbitrary number of letters:
class String
def upcase_letters
self.upcase.split(//)
end
end
module Enumerable
def reverse_with_index
self.map.with_index.to_a.reverse
end
def sum
self.reduce(0, :+)
end
end
def indexFromColumnName(column_str)
start = 'A'.ord - 1
column_str.upcase_letters.map do |c|
c.ord - start
end.reverse_with_index.map do |value, digit_position|
value * (26 ** digit_position)
end.sum - 1
end
I've added some methods to String and Enumerable because I thought it made the code more readable, but you could inline these or define them elsewhere if you don't like that sort of thing.
We can use modulo and the length of the input. The last character will
be used to calculate the exact "position", and the remainders to count
how many "laps" we did in the alphabet, e.g.
def column_to_integer(column_name)
letters = /[A-Z]+/.match(column_name).to_s.split("")
laps = (letters.length - 1) * 26
position = ((letters.last.ord - 'A'.ord) % 26)
laps + position
end
Using decimal representation (ord) and the math tricks seems a neat
solution at first, but it has some pain points regarding the
implementation. We have magic numbers, 26, and constants 'A'.ord all
over.
One solution is to give our code better knowlegde about our domain, i.e.
the alphabet. In that case, we can switch the modulo with the position of
the last character in the alphabet (because it's already sorted in a zero-based array), e.g.
ALPHABET = ('A'..'Z').to_a
def column_to_integer(column_name)
letters = /[A-Z]+/.match(column_name).to_s.split("")
laps = (letters.length - 1) * ALPHABET.size
position = ALPHABET.index(letters.last)
laps + position
end
The final result:
> column_to_integer('F5')
=> 5
> column_to_integer('AK14')
=> 36
HTH. Best!
I have found particularly neat way to do this conversion:
def index_from_column_name(colname)
s=colname.size
(colname.to_i(36)-(36**s-1).div(3.5)).to_s(36).to_i(26)+(26**s-1)/25-1
end
Explanation why it works
(warning spoiler ;) ahead). Basically we are doing this
(colname.to_i(36)-('A'*colname.size).to_i(36)).to_s(36).to_i(26)+('1'*colname.size).to_i(26)-1
which in plain English means, that we are interpreting colname as 26-base number. Before we can do it we need to interpret all A's as 1, B's as 2 etc. If only this is needed than it would be even simpler, namely
(colname.to_i(36) - '9'*colname.size).to_i(36)).to_s(36).to_i(26)-1
unfortunately there are Z characters present which would need to be interpreted as 10(base 26) so we need a little trick. We shift every digit 1 more then needed and than add it at the end (to every digit in original colname)
`

Sorting data by groups in Excel

So, I've looked around and tried to solve this on my own. This isn't an absolutely crucial question currently, I just want to know if it could be done.
So let's say I've got a list with some data that looks like
Date Location
01/24/14 H-12
01/25/14 BB-44
01/30/14 G-12
01/29/14 7A-55
01/28/14 NN-15
01/24/14 GG-47
What I want is to be able to sort the data by Location, but I don't want it to be the general way, otherwise I'll end up with 7A-55, BB-44, G-12, H-12, NN-15. I want the data to be sorted so that double letters and single letters are sorted together. E.G. it should be G-12, H-12, BB-44, NN-15, 7A-55 once everything has been sorted.
I've tried creating a custom list sort, but it doesn't work. the way intended. The custom list I tried was A-Z, AA-ZZ, 7A (items were listed out, but for saving space I wrote them like that).
Like I said, this isn't a particularly huge deal if it can't be done, it just would have made it a little easier.
Edit 1 Here is what I would like to be the output
Date Location
01/30/12 G-12
01/24/14 H-12
01/25/14 BB-44
01/24/14 GG-47
01/28/14 NN-15
01/29/14 7A-55
Edit
All of these worked in the regards i wanted to, although if I had to choose a favorite it would be the base 36 number conversion one. That was some real out-of-the-box thinking and the math geek in me appreciated it. Thanks everyone!
Well it works, but is a bit complex, so rather just for fun:
This UDF returns a value that can be used as sort key. It transforms the code into a four-digit base 36-number, i.e. using A-Z and 0-9 as symbols (like hex uses 0-9 and A-F). To get at your desired output, I literally put the symbols in this order, letters first (so "A" = 0 and "0" = 26).
(The missing 'digits' are filled up with zeros, which are in this case "A"s)
It works ;)
Public Function Base36Transform(r As Range) As Long
Dim s As String, c As String
Dim v
Dim i As Integer
Dim rv As Long
v = Split(r.Text, "-")
s1 = v(0)
s2 = v(1)
s = Right("A" & s1, 2) & Right("A" & s2, 2)
rv = 0
For i = 1 To Len(s)
c = Mid(s, Len(s) - i + 1, 1)
If c Like "#" Then
rv = rv + (Val(c) + 26) * (36 ^ (i - 1))
Else
' c is like "[A-Z]"
rv = rv + (Asc(c) - Asc("A")) * (36 ^ (i - 1))
End If
Next
Base36Transform = rv
End Function
Sorting is often a very creative process. VBA can ease up the process, but a little extension of the data will work just as well.
See my results:
The way I did it is by getting the length of each string, just to be safe. This is gotten by simply going =LEN(B2), dragged down.
Then I check if it starts with 7. If it does, assign 1, otherwise keep at 0. I used this formula: =(LEFT(B2,1)="7")*1, dragged down.
Now, my custom sort is this:
Now I might have gotten some things wrong here, or I might even have done overkill by going the Length column. However, the logic is pretty much what you're aiming for.
Hope this helps in a way! Let us know. :)
I am a little lazy here and assuming your data sits in Column A,B. You mightneed to adjust your range or the starting point of your list. But here's the code:
Sub sortttttt()
Dim rng As Range
Dim i As Integer
Range("B2").Activate
Do While Not IsEmpty(ActiveCell)
ActiveCell.Value = Len(ActiveCell.Value) & ActiveCell.Value
ActiveCell.Offset(1, 0).Activate
Loop
Set rng = Range("A1:B6")
rng.Sort Key1:=Range("B2"), Order1:=xlAscending, Header:=xlYes
Range("B2").Activate
Do While Not IsEmpty(ActiveCell)
ActiveCell.Value = Right(ActiveCell.Value, Len(ActiveCell.Value) - 1)
ActiveCell.Offset(1, 0).Activate
Loop
End Sub
Assuming your data is in columns B:C with labels in Row1 and no intervening blank rows, add a column with:
=IF(ISNUMBER(VALUE(LEFT(C2))),3,IF(FIND("-",C2)>2,2,1))
in D1 copied down to suit and sort ascending Location within sort ascending of the added column.

What is the pythonic way to print values right aligned?

I've a list of strings which I want to group by their suffix and then print the values right-aligned, padding the left side with spaces.
What is the pythonic way to do that?
My current code is:
def find_pos(needle, haystack):
for i, v in enumerate(haystack):
if str(needle).endswith(v):
return i
return -1
# Show only Error and Warning things
search_terms = "Error", "Warning"
errors_list = filter(lambda item: str(item).endswith(search_terms), dir(__builtins__))
# alphabetical sort
errors_list.sort()
# Sort the list so Errors come before Warnings
errors_list.sort(lambda x, y: find_pos(x, search_terms) - find_pos(y, search_terms))
# Format for right-aligning the string
size = str(len(max(errors_list, key=len)))
fmt = "{:>" + size + "s}"
for item in errors_list:
print fmt.format(item)
An alternative I had in mind was:
size = len(max(errors_list, key=len))
for item in errors_list:
print str.rjust(item, size)
I'm still learning Python, so other suggestions about improving the code is welcome too.
Very close.
fmt = "{:>{size}s}"
for item in errors_list:
print fmt.format(item, size=size)
The two sorting steps can be combined into one:
errors_list.sort(key=lambda x: (x, find_pos(x, search_terms)))
Generally, using the key parameter is preferred over using cmp. Documentation on sorting
If you are interested in the length anyway, using the key parameter to max() is a bit pointless. I'd go for
width = max(map(len, errors_list))
Since the length does not change inside the loop, I'd prepare the format string only once:
right_align = ">{}".format(width)
Inside the loop, you can now do with the free format() function (i.e. not the str method, but the built-in function):
for item in errors_list:
print format(item, right_align)
str.rjust(item, size) is usually and preferrably written as item.rjust(size).
You might want to look here, which describes how to right-justify using str.rjust and using print formatting.

Resources