Ruby: dealing with booleans: How to address not using military time for a clock Class - boolean

TDD
gem 'minitest', '~> 5.2'
require 'minitest/autorun'
require 'minitest/pride'
require_relative 'clock'
class ClockTest < Minitest::Test
def test_start_at_6
clock = Clock.new
assert_equal 6, clock.time
end
def test_passage_of_time
clock = Clock.new
clock.wait
assert_equal 7, clock.time
3.times { clock.wait }
assert_equal 10, clock.time
end
def test_clocks_are_not_military_time
clock = Clock.new
8.times { clock.wait }
assert_equal 2, clock.time
end
end
CODE
class Clock
attr_reader :time
def initialize
#time = 6
end
def wait(time = 1)
#time += time
end
def not_military_time
#time += (time - 10)
end
end
Can anyone guide me into figuring out how to address that the clocks are not in military time? It's coming as Expected : 2 , Actual : 14. I feel like there needs to be some of subtraction going in order to address the clock saying 2 instead of 14.
I know what I have in the code does not work, but am I on the right track?

If you look through all of the tests you'll see that apart from test_start_at_6 each test essentially calls wait some number of times and then checks for the right time in clock.time.
If you look at your code, clock.time is generated by attr_reader and so all it will ever do is return the current value of #time. So this leaves you with wait as a place to implement the behaviour needed to make the tests pass.
One other thing to notice is that you're currently overcomplicating the wait method. It's never called with any parameters and so the time parameter isn't needed. So to start simplify that to just:
def wait
#time += 1
end
Next, step away from the code and make a little list showing for each current time what the next time needs to be after wait is called. You can then think about how to change wait so that it matches that required behaviour.
In terms of whether to use an if or a case statement, everything that you could achieve using a case statement can also be done with an if as an alternative. It's best to think about the most common use of a case statement which is for checking the same variable for various possible values. i.e. the case statement
case #time
when 1
puts "One o'clock"
when 2
puts "Two o'clock"
else
puts "Later!"
end
is the same as:
if #time == 1
puts "One o'clock"
elsif #time == 2
puts "Two o'clock"
else
puts "Later!"
end
Often when you're just working out what some logic needs to be you'll write it as an if statement and then once it's working realise that it can more elegantly be expressed as a case statement. In this exercise an if should be fine.

Related

randcase weight behaviour unexpected

class test1;
function test_randcase();
for (int idx=0; idx < 10; idx++) begin
randcase
50: begin
$display("displaying from first cases");
end
50: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
program main;
initial begin
test1 t1=new();
t1.test_randcase();
end
endprogram
Since each case is equally weighed here (50/100=0.5) so the expectation is that I would see each display 5 times in total. However, I see "first case" print 6 times and "second case" print 4 times. If this is the behavior of randcase, then how would I achieve my intention of equal weight? I used vcs compiler for this execution.
output:
displaying from second case
displaying from first cases
displaying from first cases
displaying from first cases
displaying from first cases
displaying from second case
displaying from first cases
displaying from second case
displaying from second case
displaying from first cases
Looking at this problem another way, suppose you had to choose a completely random 10-bit number where each bit has a 50% chance of being 0 or 1. There are 1024 possible numbers with a 1/1024 chance of having 10 1's and a 1/1024 chance of having 10 0's. And the odds of choosing a number with exactly 5 1's and 5 0's is around 25%. If you run more iterations, your randcase distribution would approach 0.50, but the odds of getting an exact 0.5 distribution diminish.
If your requirement is getting an exact distribution, you need to know upfront how many iterations you plan to have. There are several approaches you could take, one of which I can show you
class test1;
enum {FIRST, SECOND} itor[10];
function new;
itor[0:4] = '{5{FIRST}};
itor[5:9] = '{5{SECOND}};
endfunction
function void test_randcase();
itor.shuffle();
foreach(itor[i]) begin
case(itor[i])
FIRST: begin
$display("displaying from first cases");
end
SECOND: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
module main;
test1 t1=new();
initial repeat(10)begin
$display("---");
t1.test_randcase();
end
endmodule
Other ways are shown in my paper from DVCon 2020, SystemVerilog Constraints: Appreciating What You Forgot in School to Get Better Results

Why doe `later` method lead to infinite range in `Date` range?

In Julia, you may generate a date range by month like this:
julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)
Date("2014-01-29"):Month(1):Date("2014-07-29")
julia> collect(dr)
7-element Array{Date,1}:
2014-01-29
2014-02-28
2014-03-29
2014-04-29
2014-05-29
2014-06-29
2014-07-29
Date(2014,1,29) is the start date, Dates.Month(1) is the step, Date(2014,07,29) is the end date.
Raku has a method later, but when used in custom generator, it lead to infinite range:
lazy my #dates = Date.new('2014-01-29'), Date.new('2014-02-28'), { $^a.later(:1month) } ... Date.new('2014-07-29')
If I use * >= Date.new('2014-07-29') instead of Date.new('2014-07-29') on the right of ... operator, it works:
lazy my #a = Date.new('2014-01-29'), Date.new('2014-02-28'), { $^a.later(:1month) } ... * >= Date.new('2014-07-29')
2014-01-29
2014-02-28
2014-03-28
2014-04-28
2014-05-28
2014-06-28
2014-07-28
2014-08-28
why the custom generator { $^a.later(:1month) } in the { $^a.later(:1month) } ... Date.new('2014-07-29') doesn't stop at 2014-07-29 and lead to infinite range?
As JJMerelo indicates in the comments, the way that the ... operator works is to continue generating elements based on the left-hand-arguments until the right-hand-argument is (per smartmatching) exactly reached.
For example, if we made a sequence of multiples of 10s,
my #tens = 0, 10, 20 ... 95;
say #tens[10]; # 100
say #tens[11]; # 110
This is because not element of #tens will actually be 95. To determine if an element is the final one, the smartmatch operator (~~) is used. Smartmatching a DateTime with another Datetime returns true if the two represent the same time (which may be different nominal times because of timezones, etc).
For sequences, DateTime is further complicated by the fact that .later and .earlier are not communative, so doing $date.later(:1month).later(:1month) is not guaranteed to give the same result as $date.later(:2month).
The reason that * ≥ DateTime.new(…) is different is that smartmatching for Callable objects (which that technically is, it's whatever code equivalent to anon sub $dt { $dt ≥ DateTime.new(…) } passes the left hand argument to the callable. If you're not 100% sure that a sequence will terminate by reaching an exact value, it's best to use the whatever code approach to ensure a value eventually matches.
Hmmm - for any kids out there trying this, there are some pitfalls to do with "what I mean"... for example when I try this
lazy my #b = Date.new('2014-01-31'), Date.new('2014-02-28'), { $^a.later(:1month) } ... * >= Date.new('2014-07-29')
I get this...
#(2014-01-31 2014-02-28 2014-03-28 ...)
But maybe I wanted the last day of each month, what if 2014 is a leap year, blah, blah
So if you want the last day (or last day -1), then there is also this handy method...
say Date.new('2015-11-24').last-date-in-month;

Incremental increase of a variable over time

I am usually programming in Python, but for an assignment, I am using Simulink. I am wondering why the above elseif ladder does not generate an incremental increase of the variable [IP3] over time. What I would think it should do is return 0.01 until t = 500, then 0.03 until t = 1000, then 0.1 until 1500, 1 until 2000, and 10 from then on. Apologies for the older image btw, I updated the variables in the mean time.
In the Simulink model that you showed, elseif parts will never execute since:
if u1>0 is satisfied, none of the other conditions will be checked and thus it will always be returning 0.01 for all u1>0.
And when u1<=0, all the conditions will be checked but none of them
will be satisfied. (u1 may never be less than zero in your case as u1 is time).
This behavior is same in every programming language.
Fixing your If-elseif Statements:
You need to add this in the If block:
Under If expression (e.g. u1 ~= 0), write this:
u1>0 & u1<=500
Under Elseif expressions (comma-separated list, e.g. u2 ~= 0, u3(2) < u2):, write this:
u1>500 & u1<=1000, u1>1000 & u1<=1500, u1>1500 & u1<=2000, u1>2000
Since u1 is time in your case which cannot be negative, you may also want to use the else part. So instead of the last step you can also do this:
Under Elseif expressions (comma-separated list, e.g. u2 ~= 0, u3(2) < u2):, write this:
u1>500 & u1<=1000, u1>1000 & u1<=1500, u1>1500 & u1<=2000
and connect the output of the else part which was connected with the output of u1>2000 before.

Problems with simple time measurement in scala

I try to "profile" an expensive method by the means of just printing the system time. I've written a small method that prints the current time in seconds relative to the start-time. :
object Bechmark extends App {
var starttime = 0L
def printTime(): Unit = {
if (starttime == 0L) {
starttime = System.currentTimeMillis()
}
println((System.currentTimeMillis() - starttime) / 1000.0)
}
printTime()
Thread.sleep(100)
printTime()
}
I expect therefore that the first call to printTime prints something close to 0. But the output I get is
0.117
0.221
I don't understand why the first call already gives me ~120 miliseconds? What is the correct implementation for my purpose?
As others have mentioned the running time of your application does not necessarily represent the actual world time elapsed. There are several factors that affect it: warm up time of the JVM, JVM garbage collection, steady state of the JVM for the accurate measurement, OS process dispatching and shuffling.
For Scala-related purposes I suggest ScalaMeter
that allows you to tune all the aforementioned variables and measure the time quite accurately.

Which costs more while looping; assignment or an if-statement?

Consider the following 2 scenarios:
boolean b = false;
int i = 0;
while(i++ < 5) {
b = true;
}
OR
boolean b = false;
int i = 0;
while(i++ < 5) {
if(!b) {
b = true;
}
}
Which is more "costly" to do? If the answer depends on used language/compiler, please provide. My main programming language is Java.
Please do not ask questions like why would I want to do either.. They're just barebone examples that point out the relevant: should a variable be set the same value in a loop over and over again or should it be tested on every loop that it holds a value needed to change?
Please do not forget the rules of Optimization Club.
The first rule of Optimization Club is, you do not Optimize.
The second rule of Optimization Club is, you do not Optimize without measuring.
If your app is running faster than the underlying transport protocol, the optimization is over.
One factor at a time.
No marketroids, no marketroid schedules.
Testing will go on as long as it has to.
If this is your first night at Optimization Club, you have to write a test case.
It seems that you have broken rule 2. You have no measurement. If you really want to know, you'll answer the question yourself by setting up a test that runs scenario A against scenario B and finds the answer. There are so many differences between different environments, we can't answer.
Have you tested this? Working on a Linux system, I put your first example in a file called LoopTestNoIf.java and your second in a file called LoopTestWithIf.java, wrapped a main function and class around each of them, compiled, and then ran with this bash script:
#!/bin/bash
function run_test {
iter=0
while [ $iter -lt 100 ]
do
java $1
let iter=iter+1
done
}
time run_test LoopTestNoIf
time run_test LoopTestWithIf
The results were:
real 0m10.358s
user 0m4.349s
sys 0m1.159s
real 0m10.339s
user 0m4.299s
sys 0m1.178s
Showing that having the if makes it slight faster on my system.
Are you trying to find out if doing the assignment each loop is faster in total run time than doing a check each loop and only assigning once on satisfaction of the test condition?
In the above example I would guess that the first is faster. You perform 5 assignments. In the latter you perform 5 test and then an assignment.
But you'll need to up the iteration count and throw in some stopwatch timers to know for sure.
Actually, this is the question I was interested in… (I hoped that I’ll find the answer somewhere to avoid own testing. Well, I didn’t…)
To be sure that your (mine) test is valid, you (I) have to do enough iterations to get enough data. Each iteration must be “long” enough (I mean the time scale) to show the true difference. I’ve found out that even one billion iterations are not enough to fit to time interval that would be long enough… So I wrote this test:
for (int k = 0; k < 1000; ++k)
{
{
long stopwatch = System.nanoTime();
boolean b = false;
int i = 0, j = 0;
while (i++ < 1000000)
while (j++ < 1000000)
{
int a = i * j; // to slow down a bit
b = true;
a /= 2; // to slow down a bit more
}
long time = System.nanoTime() - stopwatch;
System.out.println("\\tasgn\t" + time);
}
{
long stopwatch = System.nanoTime();
boolean b = false;
int i = 0, j = 0;
while (i++ < 1000000)
while (j++ < 1000000)
{
int a = i * j; // the same thing as above
if (!b)
{
b = true;
}
a /= 2;
}
long time = System.nanoTime() - stopwatch;
System.out.println("\\tif\t" + time);
}
}
I ran the test three times storing the data in Excel, then I swapped the first (‘asgn’) and second (‘if’) case and ran it three times again… And the result? Four times “won” the ‘if’ case and two times the ‘asgn’ appeared to be the better case. This shows how sensitive the execution might be. But in general, I hope that this has also proven that the ‘if’ case is better choice.
Thanks, anyway…
Any compiler (except, perhaps, in debug) will optimize both these statements to
bool b = true;
But generally, relative speed of assignment and branch depend on processor architecture, and not on compiler. A modern, super-scalar processor perform horribly on branches. A simple micro-controller uses roughly the same number of cycles per any instruction.
Relative to your barebones example (and perhaps your real application):
boolean b = false;
// .. other stuff, might change b
int i = 0;
// .. other stuff, might change i
b |= i < 5;
while(i++ < 5) {
// .. stuff with i, possibly stuff with b, but no assignment to b
}
problem solved?
But really - it's going to be a question of the cost of your test (generally more than just if (boolean)) and the cost of your assignment (generally more than just primitive = x). If the test/assignment is expensive or your loop is long enough or you have high enough performance demands, you might want to break it into two parts - but all of those criteria require that you test how things perform. Of course, if your requirements are more demanding (say, b can flip back and forth), you might require a more complex solution.