Testing a legacy code [closed] - testing

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm following a course in agile practices and I have a homework. What they taught me, is that before changing the code (refactoring or adding functionality) I should add some test, in order to gain confidence and be sure that I will not change the behavior while refactoring. This is clear and makes sense, but what if the code is not testable without doing some refactoring first?
Simple example:
public class Summation
{
private int addend1;
private int addend2;
public Summation(int addend1, int addend2)
{
this.addend1 = addend1;
this.addend2 = addend2;
}
public int doSum()
{
System.out.println(addend1 + addend2);
}
// Getters/setters
}
I would like to run an acceptance/integration test using FIT, and check that the following table is verified:
----------------------------
| addend1 | addend2 | result |
----------------------------
| 1 | 1 | 2 |
----------------------------
| 1 | -1 | 0 |
----------------------------
| -1 | 1 | 0 |
----------------------------
| -1 | -1 | -2 |
----------------------------
But, because the function doSum() prints the sum to the standard output stream, it's difficult to write a test for it (I prefer to avoid to intercept the standard output). It would make more sense to slightly refactor the code in order to have a method that returns the sum. But because I'm technically "not allowed" to change the code before writing any test, this is not recommended.
Can you give me any hints? How would you proceed?
Thank you!

Sounds similar to this question.
Whether or not you're allowed to change the code, you're forced to intercept standard output stream. In any case, it's a part of the behaviour.

You could write a test.cpp file to call Summation.Summation(x,y) with various values for x and y in your table and verify/record the results. Make sure the results are what you expect. Next, you may now edit the Summation class and run your tests again (from test.cpp) to ensure the values are the same as they were initially.

Related

How to sort by proximity? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm building an app that recommends people to other people based on how frequently they've been to the same place.
So for a given person A (the one you want to give a suggestion), I have a table of all others persons and the amount of time they've been to a place. i.e, I get this:
idPerson | idPlace | nbTimesPersonWent | nbTimesPersonAWent
10 | 1 | 3 | 10
11 | 2 | 1 | 22
12 | 1 | 11 | 10
13 | 3 | 8 | 2
What I'm struggling with is finding which of these idPerson is the "best" person to recommend to A.
Is there a way (preferably pure SQL), to sort this table from "closer" value of nbTimesPersonWent and nbTimesPersonWent to "less close" values?
I would recommend using the following tables
Person:
id
Place:
id
Visit:
person_id, place_id, time_spent
Now you must choose which way you will sort people that are interesting to a particular person a.
Many different sort functions exists. For any person of interest a, you can rank any other person b based on many different criteria. For example:
f(a,b) = Sum of min_time(a,b,p) for all places p that both a and b have visited, where min_time(a,b,p) = minimum of the time a and b have spent at place p
f(a,b) = The number of places that both a and b have visited
The difference between the two methods is that the first consider the time spent at different places and that the second only considers the number of places commonly visited. You can also define functions that limits the impact of having spent much time the same place, compared to distributing that time over multiple places.
If you can specify an exact ranking criteria, I will be happy to help you write a query for it.
UPDATE: Here is an example of sorting by the 2nd ranking criteria. That is, by the number of visited places in common: sqlfiddle.com/#!9/b56745/1/0

pad/truncate strings [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Today i went for my first interview for .Net Developer.
Interviewer asked me one tricky question but I can't able to answer that.
I thought lots on that question but not get any solution on that question.
Question is...
ID | Name
1 | Ram
2 | Prathamesh
3 | Naresh
4 | Dasharath
Update this table with following condition;
If Name's character is less than 6 letters then New value must be like "Ram***"
(* mark will be added until characters length is 6)
and if it more than 6 letters all extra letters should be remove.
Result like this :
ID | Name
1 | Ram*** /* added three * marks */
2 | Pratha /* removed extra letters */
3 | Naresh /* No changes */
4 | Dashar /* removed extra letters */
SELECT LEFT(NAME+'******',6) FROM TABLE

Ascending and Decending ORDER BY clauses in a single query [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I working on these problems for a class I"m taking, but this one has me stumped. Here is the problem:
--Using the AUTHOR table, write a query that will list all information about authors
--whose first name ends with an “A”. Put the results in descending order of last name,
--and then ascending order by first name. This should be done using a single query.
Here is what I've come up with so far:
SELECT *
FROM author
WHERE(fname LIKE '%A')
ORDER BY lname DESC, fname ASC;
However all I get in the result is the information ordered by last name descending. First name ascending doesn't seem to work.
Any thoughts on what I'm missing? Using Oracle Express 10G, if it matters.
Thanks.
There is nothing wrong with your query. All you have to do is just pay attention to the data :-)
Here is how you would interpret your data output:
--------------+--------------
zzz | john
zza | adam
zaa | bob
ccc | jack
ccc | john
cca | mike
So, ordering works just you instruct Oracle - lname desc, fname acs, but you need to realize that fname asc comes in a picture once lname desc is processed. In other words: ZZZ comes before ZZA , but once CCC is ordered then and only then jack comes before john .

Homoiconicity and SQL

I'm currently using emacs sql-mode as my sql shell, a (simplified) query response is below:
my_db=# select * from visit limit 4;
num | visit_key | created | expiry
----+-----------------------------+----------------------------+------------
1 | 0f6fb8603f4dfe026d88998d81a | 2008-03-02 15:17:56.899817 | 2008-03-02
2 | 7c389163ff611155f97af692426 | 2008-02-14 12:46:11.02434 | 2008-02-14
3 | 3ecba0cfb4e4e0fdd6a8be87b35 | 2008-02-14 16:33:34.797517 | 2008-02-14
4 | 89285112ef2d753bd6f5e51056f | 2008-02-21 14:37:47.368657 | 2008-02-21
(4 rows)
If I want to then formulate another query based on that data, e.g.
my_db=# select visit_key, created from visit where expiry = '2008-03-02'
and num > 10;
You'll see that I have to add the comma between visit_key and created, and surround the expiry value with quotes.
Is there a SQL DB shell that shows it's content more homoiconically, so that I could minimise this sort of editing? e.g.
num, visit_key, created, expiry
(1, '0f6fb8603f4dfe026d88998d81a', '2008-03-02 15:17:56.899817', '2008-03-02')
or
(num=1, visit_key='0f6fb8603f4dfe026d88998d81a',
created='2008-03-02 15:17:56.899817', expiry='2008-03-02')
I'm using postgresql btw.
Here's one idea, which is similar to what I do sometimes, though I'm not sure that it's exactly what you're asking for:
Run a Lisp compiler (like SBCL) in SLIME. Then load CLSQL. It has a "Functional Data Manipulation Language" (SELECT documentation) which might help you do something like you want, perhaps in conjunction with SLIME's autocompletion capabilities. If not, it's easy to define Lisp functions and macros (assuming you know Lisp, but you're already an Emacser!).
Out-of-the-box, it doesn't give the nicely formatted tables that most SQL interfaces have, but even that isn't too hard to add. And Lisp is certainly powerful enough to let one easily come up with ways to make your common operations easier.
I've found the following changes in psql go some way to giving me homoiconicity:
=# select remote_ip, referer, http_method, time from hit limit 1;
remote_ip | referer | http_method | time
-----------------+---------+-------------+---------------------------
213.233.132.148 | | GET | 2013-08-27 08:01:42.38808
(1 row)
=# \a
Output format is unaligned.
=# \f ''', '''
Field separator is "', '".
=# \t
Showing only tuples.
=# select remote_ip, referer, http_method, time from hit limit 1;
213.233.132.148', '', 'GET', '2013-08-27 08:01:42.38808
caveats: everything is a string, and it's missing start and end quotes.

cloning hierarchical data

let's assume i have a self referencing hierarchical table build the classical way like this one:
CREATE TABLE test
(name text,id serial primary key,parent_id integer
references test);
insert into test (name,id,parent_id) values
('root1',1,NULL),('root2',2,NULL),('root1sub1',3,1),('root1sub2',4,1),('root
2sub1',5,2),('root2sub2',6,2);
testdb=# select * from test;
name | id | parent_id
-----------+----+-----------
root1 | 1 |
root2 | 2 |
root1sub1 | 3 | 1
root1sub2 | 4 | 1
root2sub1 | 5 | 2
root2sub2 | 6 | 2
What i need now is a function (preferrably in plain sql) that would take the id of a test record and
clone all attached records (including the given one). The cloned records need to have new ids of course. The desired result
would like this for example:
Select * from cloningfunction(2);
name | id | parent_id
-----------+----+-----------
root2 | 7 |
root2sub1 | 8 | 7
root2sub2 | 9 | 7
Any pointers? Im using PostgreSQL 8.3.
Pulling this result in recursively is tricky (although possible). However, it's typically not very efficient and there is a much better way to solve this problem.
Basically, you augment the table with an extra column which traces the tree to the top - I'll call it the "Upchain". It's just a long string that looks something like this:
name | id | parent_id | upchain
root1 | 1 | NULL | 1:
root2 | 2 | NULL | 2:
root1sub1 | 3 | 1 | 1:3:
root1sub2 | 4 | 1 | 1:4:
root2sub1 | 5 | 2 | 2:5:
root2sub2 | 6 | 2 | 2:6:
root1sub1sub1 | 7 | 3 | 1:3:7:
It's very easy to keep this field updated by using a trigger on the table. (Apologies for terminology but I have always done this with SQL Server). Every time you add or delete a record, or update the parent_id field, you just need to update the upchain field on that part of the tree. That's a trivial job because you just take the upchain of the parent record and append the id of the current record. All child records are easily identified using LIKE to check for records with the starting string in their upchain.
What you're doing effectively is trading a bit of extra write activity for a big saving when you come to read the data.
When you want to select a complete branch in the tree it's trivial. Suppose you want the branch under node 1. Node 1 has an upchain '1:' so you know that any node in the branch of the tree under that node must have an upchain starting '1:...'. So you just do this:
SELECT *
FROM table
WHERE upchain LIKE '1:%'
This is extremely fast (index the upchain field of course). As a bonus it also makes a lot of activities extremely simple, such as finding partial trees, level within the tree, etc.
I've used this in applications that track large employee reporting hierarchies but you can use it for pretty much any tree structure (parts breakdown, etc.)
Notes (for anyone who's interested):
I haven't given a step-by-step of the SQL code but once you get the principle, it's pretty simple to implement. I'm not a great programmer so I'm speaking from experience.
If you already have data in the table you need to do a one time update to get the upchains synchronised initially. Again, this isn't difficult as the code is very similar to the UPDATE code in the triggers.
This technique is also a good way to identify circular references which can otherwise be tricky to spot.
The Joe Celko's method which is similar to the njreed's answer but is more generic can be found here:
Nested-Set Model of Trees (at the middle of the article)
Nested-Set Model of Trees, part 2
Trees in SQL -- Part III
#Maximilian: You are right, we forgot your actual requirement. How about a recursive stored procedure? I am not sure if this is possible in PostgreSQL, but here is a working SQL Server version:
CREATE PROCEDURE CloneNode
#to_clone_id int, #parent_id int
AS
SET NOCOUNT ON
DECLARE #new_node_id int, #child_id int
INSERT INTO test (name, parent_id)
SELECT name, #parent_id FROM test WHERE id = #to_clone_id
SET #new_node_id = ##IDENTITY
DECLARE #children_cursor CURSOR
SET #children_cursor = CURSOR FOR
SELECT id FROM test WHERE parent_id = #to_clone_id
OPEN #children_cursor
FETCH NEXT FROM #children_cursor INTO #child_id
WHILE ##FETCH_STATUS = 0
BEGIN
EXECUTE CloneNode #child_id, #new_node_id
FETCH NEXT FROM #children_cursor INTO #child_id
END
CLOSE #children_cursor
DEALLOCATE #children_cursor
Your example is accomplished by EXECUTE CloneNode 2, null (the second parameter is the new parent node).
This sounds like an exercise from "SQL For Smarties" by Joe Celko...
I don't have my copy handy, but I think it's a book that'll help you quite a bit if this is the kind of problems you need to solve.