Can you please tell me how to calculate the lowest and highest number in this list using python - web.py

markList=[]
while True:
mark=float(input("Enter your marks here(Click -1 to exit)"))
if mark == -1: break
markList.append(mark)
markList.sort()
mid = len(markList)//2
if len(markList)%2==0:
median=(markList[mid]+ markList[mid-1])/2
print("Median:", median)
else:
print("Median:" , markList[mid]) #please do not touch anything starting from this line and above, I have already found the median with this and all Im looking for it to
find out the lowest and highest grades, this program is asking for the user to input their grades and it telss you the highest, lowest and grade average
min(mark)
print("The lowest mark is", min(mark))
max(mark)
print("The highest mark is", max(mark))

I'm not a Python expert by any stretch but I've learned some basics. You can refer to the documentation on the list object here:
http://docs.python.org/2/library/functions.html#max
list objects in python allow a min() and max() function. You can call these even before you sort the list, for example:
print min(marklist) or print max(marklist).
Since you've already sorted the list to do your median calculation, you could also just retrieve the first and last item in the list, as the lowest & highest marks, respectively:
print marklist[0] #prints the first/0-index position in the list
And likewise the maximum value, since python supports reverse-indexing of list objects:
print marklist[-1] #prints the last position in the list
I tested it with this simple code:
marklist=[]
marklist=[10,13,99,4,3,5,1,0,22,11,6,5,38]
print min(marklist),max(marklist)
marklist.sort()
print marklist[0],marklist[-1]

Related

How to access last argument in PowerShell script (args)

I have following code:
foreach ($arg in $args) {
Write-Host "Arg: $arg";
$param1=$args[0]
}
Write-host "Number of args: " $args.Length
write-host Last Arg is: "$($args.count)"
I get this, when I run it:
./print_last_arg.ps1 a b c
Arg: a
Arg: b
Arg: c
Number of args: 3
Last Arg is: 3
What I would like to have is name of last argument, so:
Last Arg is: 3
should be:
Last Arg is: c
Sorry for such a stupid question but I am totally begginer in PS and cannot google the result...
PowerShell supports negative indices to refer to elements from the end of a collection, starting with -1 to refer to the last element, -2 to the penultimate (second to last) one, and so on.
Therefore, use $args[-1] to refer to the last argument passed.
For more information, see the conceptual about_Arrays help topic.
Note that you can also use the results of expressions as indices; e.g., the equivalent of $args[-1] is $args[$args.Count-1] (assuming the array has at least one element).
Additionally, you may specify multiple indices to extract a sub-array of arbitrary elements. E.g., $args[0, -1] returns a (new) array comprising the input array's first and the last element (assuming the array has at least two elements).
.., the range operator is particularly useful for extracting a range of contiguous elements. E.g., $args[0..2] returns a (new) array comprising the first 3 elements (the elements with indices 0, 1, and 2).
You can even combine individual indices with ranges, courtesy of PowerShell's + operator performing (flat) array concatenation.
E.g., $args[0..2 + -1] extracts the first 3 elements as well as the last (assumes at least 4 elements).
Note: For syntactic reasons, if a single index comes first in the index expression, you need to make it an array with the unary form of , the array constructor operator, to make sure that + performs array concatention; e.g., $args[,-1 + 0..2] extracts the last element followed by the first 3.
Pitfall: Combining a positive .. start point with a negative end point for up-to-the-last-Nth-element logic does not work as intended:
Assume the following array:
$a = 'first', 'middle1', 'middle2', 'last'
It is tempting to use range expression 1..-2 to extract all elements "in the middle", i.e. starting with the 2nd and up to the penultimate element - but this does not work as expected:
# BROKEN attempt to extract 'middle1', 'middle2'
PS> $a[1..-2]
middle1
first
last
middle2
The reason is that 1..-2, as a purely arithmetic range expression, expanded to the following array (whose elements happen to be used as indices into another array): 1, 0, -1, -2. And it is these elements that were extracted: the 2nd, the first, the last, the penultimate.
To avoid this problem, you need to know the array's element count ahead of time, and use an expression to specify the end of the range as a positive number:
# OK: extract 'middle1', 'middle2'
# Note that the verbosity and the need to know $a's element count.
PS> $a[1..($a.Count-2)]
middle1
middle2
Unfortunately, this is both verbose and inconvenient, especially given that you may want to operate on a collection whose count you do not know in advance.
GitHub issue #7940 proposes a future enhancement to better support this use case with new syntax, analogous to C#'s indices-and-ranges feature, so that the above could be written more conveniently with syntax such as $a[1..^1]

Why does this line return sum of integers 1-10?

I'd like to understand how unpack is returning the sum in the given perl one-liner.
I've looked at pack man page and mostly understood that it is simply formatting the given array into a scalar of ten doubles.
However, I couldn't find proper documentation for unpack with %123. Looking for help here.
print unpack "%123d*" , pack( "d*", (1..10));
This line correctly outputs 55 which is 1+2+3+...+10.
From perldoc -f unpack:
In addition to fields allowed in pack(), you may prefix a field with a % to indicate that you want a <number>-bit checksum of the items instead of the items themselves.
Thus %123d* means to add all the input integers 1..10 and then take the first 123 bit of this result in order to construct the "<number>-bit checksum". Note that %8d* or just %d* (which is equivalent to %16d*) would suffice too given that the sum is small enough.

Exponential values manipulation in perl

I have a select statement which return capacity as exponential value e.g.
Capacity=5.4835615662E+003
in Perl code
I am using a db2 database, and if I explicitly run a query in database it returns
5483.5615662
but when I use next select query when I use capacity value in condition it doesn't match
e.g. pseudo code is as below,
my $capacity = 'SELECT capacity FROM table';
# it returns $capacity = 5.4835615662E+003
my $result = "SELECT MEASUREMENT FROM TABLE WHERE CAPACITY = $capacity";
Here $capacity is 5.4835615662E+003, so it does not match any row in the table. It should be 5483.5615662.
How to convert exponential value to float without rounding off?
You are interpolating the value of $capacity into a string. Instead, you should use placeholders as in:
my $sth = $dbh->prepare(q{SELECT MEASUREMENT FROM TABLE WHERE CAPACITY=?});
$sth->execute($capacity);
It is hard to say if there are any other problems because the code snippets you provide don't really do anything.
It is likely that the number stored in the database is not exactly 5483.5615662 and that is just the displayed string when you query it.
If possible, I would recommend taking #Сухой27's advice and letting the database do the work for you:
SELECT MEASUREMENT FROM TABLE
WHERE CAPACITY = (SELECT CAPACITY FROM TABLE where ..?)
Alternatively, decide ahead of time how many digits past the decimal point really matter and use ROUND or similar functionality:
my $sth = $dbh->prepare(q{
SELECT MEASUREMENT FROM TABLE
WHERE ROUND(CAPACITY, 6)=ROUND(?, 6)
});
$sth->execute($capacity);
Please take a look at Why doesn't this sql query return any results comparing floating point numbers?
I'm concerned about the 5.4835615662+003 that you show in your question. That isn't a valid representation of a number, and it means just 5.4835615662 + 3. You need an E or an e before the exponent to use it as it is
There is also an issue with comparing floating-point values, whereby two numbers that are essentially equal may have a slightly different binary representation, and so will not compare as equal. If your value has been converted to a string (and that seems highly likely, as Perl will not use an exponent to display 5483.5615662 unless told to do so) and back again to floating point, then it is extremely unlikely to result in exactly the same value. Your comparisons will always fail
In Perl, and most other languages, a numeric values has no specific format. For example, if I run this
perl -E 'say 5.4835615662E+003'
I get the output
5483.5615662
showing that the two string representations are equivalent
It would help to see exactly how you got the value of $capacity from the database, because if it were a simple number then it wouldn't use the scientific representation. You would have to use sprintf to get what you have shown
SQL is the same and doesn't care about the format of the number as long as it's valid, so if you wrote
SELECT measurement FROM table WHERE capacity = 5.4835615662E+003
then you would get a result where capacity is exactly equal to that value. But since it has been trimmed to eleven significant digits, you are hugely unlikely to find the record that the value came from, unless it contains 5483.56156620000000000
Update
If I run
perl -MMath::Trig=pi -E 'for (0 .. 20) { $x = pi * 10**$_; say qq{$x}; }'
I get this result
3.14159265358979
31.4159265358979
314.159265358979
3141.59265358979
31415.9265358979
314159.265358979
3141592.65358979
31415926.5358979
314159265.358979
3141592653.58979
31415926535.8979
314159265358.979
3141592653589.79
31415926535897.9
314159265358979
3.14159265358979e+015
3.14159265358979e+016
3.14159265358979e+017
3.14159265358979e+018
3.14159265358979e+019
3.14159265358979e+020
So by default Perl won't resort to using scientific notation until the value reaches 1015. It clearly doesn't apply to 5483.5615662. Something has coerced the floating-point value in the question to a much less precise string in scientific notation. Comparing that for equality doesn't stand a chance of succeeding

What does this piece of Perl code do in laymans terms?

Found this inside a loop. I've read up about splice but it just confused me more.
I'm not familiar with Perl, but am trying to translate an algorithm to another language.
my $sill = splice(#list,int(rand(#list)),1);
last unless ($sill);
To be more specific: What will be inside $sill if it doesn't exit the loop from the last?
Thanks for any help!
This randomly removes one element from the array #list. That value is assigned to $sill. If that was a false value, the enclosing loop (not shown) is broken out of.
splice takes an array, an offset, and a length, plus a replacement list. If the replacement is omitted, the elements are deleted.
The length is constant (1 element), but the offset is calculated as a random integer smaller between 0 and the length of #list.
That means :
remove a random element from the array list (0 -> numbers of element of the list) and
assign the sill variable with the removed element (pop() like) and
exit the loop if sill variable is false
See http://perldoc.perl.org/functions/splice.html

Find combinations of numbers that sum to some desired number

I need an algorithm that identifies all possible combinations of a set of numbers that sum to some other number.
For example, given the set {2,3,4,7}, I need to know all possible subsets that sum to x. If x == 12, the answer is {2,3,7}; if x ==7 the answer is {{3,4},{7}} (ie, two possible answers); and if x==8 there is no answer. Note that, as these example imply, numbers in the set cannot be reused.
This question was asked on this site a couple years ago but the answer is in C# and I need to do it in Perl and don't know enough to translate the answer.
I know that this problem is hard (see other post for discussion), but I just need a brute-force solution because I am dealing with fairly small sets.
sub Solve
{
my ($goal, $elements) = #_;
# For extra speed, you can remove this next line
# if #$elements is guaranteed to be already sorted:
$elements = [ sort { $a <=> $b } #$elements ];
my (#results, $RecursiveSolve, $nextValue);
$RecursiveSolve = sub {
my ($currentGoal, $included, $index) = #_;
for ( ; $index < #$elements; ++$index) {
$nextValue = $elements->[$index];
# Since elements are sorted, there's no point in trying a
# non-final element unless it's less than goal/2:
if ($currentGoal > 2 * $nextValue) {
$RecursiveSolve->($currentGoal - $nextValue,
[ #$included, $nextValue ],
$index + 1);
} else {
push #results, [ #$included, $nextValue ]
if $currentGoal == $nextValue;
return if $nextValue >= $currentGoal;
}
} # end for
}; # end $RecursiveSolve
$RecursiveSolve->($goal, [], 0);
undef $RecursiveSolve; # Avoid memory leak from circular reference
return #results;
} # end Solve
my #results = Solve(7, [2,3,4,7]);
print "#$_\n" for #results;
This started as a fairly direct translation of the C# version from the question you linked, but I simplified it a bit (and now a bit more, and also removed some unnecessary variable allocations, added some optimizations based on the list of elements being sorted, and rearranged the conditions to be slightly more efficient).
I've also now added another significant optimization. When considering whether to try using an element that doesn't complete the sum, there's no point if the element is greater than or equal to half the current goal. (The next number we add will be even bigger.) Depending on the set you're trying, this can short-circuit quite a bit more. (You could also try adding the next element instead of multiplying by 2, but then you have to worry about running off the end of the list.)
The rough algorithm is as follows:
have a "solve" function that takes in a list of numbers already included and a list of those not yet included.
This function will loop through all the numbers not yet included.
If adding that number in hits the goal then record that set of numbers and move on,
if it is less than the target recursively call the function with the included/exluded lists modified with the number you are looking at.
else just go to the next step in the loop (since if you are over there is no point trying to add more numbers unless you allow negative ones)
You call this function initially with your included list empty and your yet to be included list with your full list of numbers.
There are optimisations you can do with this such as passing the sum around rather than recalculating each time. Also if you sort your list initially you can do optimisations based on the fact that if adding number k in the list makes you go over target then adding k+1 will also send you over target.
Hopefully that will give you a good enough start. My perl is unfortuantely quite rusty.
Pretty much though this is a brute force algorithm with a few shortcuts in it so its never going to be that efficient.
You can make use of the Data::PowerSet module which generates all subsets of a list of elements:
Use Algorithm::Combinatorics. That way, you can decide ahead of time what size subsets you want to consider and keep memory use to a minimum. Apply some heuristics to return early.
#!/usr/bin/perl
use strict; use warnings;
use List::Util qw( sum );
use Algorithm::Combinatorics qw( combinations );
my #x = (1 .. 10);
my $target_sum = 12;
{
use integer;
for my $n ( 1 .. #x ) {
my $iter = combinations(\#x, $n);
while ( my $set = $iter->next ) {
print "#$set\n" if $target_sum == sum #$set;
}
}
}
The numbers do blow up fairly rapidly: It would take thousands of days to go through all subsets of a 40 element set. So, you should decide on the interesting sizes of subsets.
Is this a 'do my homework for me' question?
To do this deterministically would need an algorithm of order N! (i.e. (N-0) * (N-1) * (N-2)...) which is going to be very slow with large sets of inputs. But the algorithm is very simple: work out each possible sequence of the inputs in the set and try adding up the inputs in the sequence. If at any point the sum matches, you've got one of the answers, save the result and move on to the next sequence. If at any point the sum is greater than the target, abandon the current sequence and move on to the next.
You could optimize this a little by deleting any of the inputs greater than the target. Another approach for optimization would be to to take the first input I in the sequence and create a new sequence S1, deduct I from the target T to get a new target T1, then check if T exists in S1, if it does then you've got a match, otherwise repeat the process with S1 and T1. The order is still N! though.
If you needed to do this with a very large set of numbers then I'd suggest reading up on genetic algorithms.
C.
Someone posted a similar question a while ago and another person showed a neat shell trick to answer it. Here is a shell technique, but I don't think it is as neat a solution as the one I saw before (so I'm not taking credit for this approach). It's cute because it takes advantage of shell expansion:
for i in 0{,+2}{,+3}{,+4}{,+7}; do
y=$(( $i )); # evaluate expression
if [ $y -eq 7 ]; then
echo $i = $y;
fi;
done
Outputs:
0+7 = 7
0+3+4 = 7