Suggestion for multi if factoring - refactoring

I have some old ugly code like this
if(!isLogin)
{
if(confirm("Login first ?"))
{
doLogin();
return;
}
else
{
doStuff1();
doStuff2();
doStuff3();
}
}
else
{
doStuff1();
doStuff2();
doStuff3();
}
For refactoring, here's what I did
if(!isLogin && confirm("Login first ?"))
{
doLogin();
}
else
{
doStuff1();
doStuff2();
doStuff3();
}
I'm not sure... is new code logic equals old part, and possible to make it shorter ?

You need to add return; after doLogin(); to be the same. You could drop the else { and } too, and unindent the three doStuff?() functions:
if (!isLogin && confirm("Login first ?"))
{
doLogin();
return;
}
doStuff1();
doStuff2();
doStuff3();

Related

How to apply compatplaylist to HwCertTestCollection

For HLK testing automation I would like to apply the compatplaylist on my test list.
Generell automation instruction, but no info how to apply a playlist.
One option is to modify the master test list based on the compatplaylist - both are xml based (with the help of Export-HwCertTestCollectionToXml and import-hwcerttestcollectionfromxml),
But maybe somebody already has a solution or knows an offical support for it.
Try this:-
public static PlaylistManager ApplyPlaylist(Project projectname, string playlistpath)
{
PlaylistManager pl_manager = null;
try
{
pl_manager = new PlaylistManager(projectname);
if (pl_manager == null)
Console.WriteLine("Cannot make playlist manager for the project:- {0}", projectname.Name.ToString());
if(pl_manager.IsPlaylistLoaded() == true)
{
Console.WriteLine("Playlist loaded.. unloading ");
pl_manager.UnloadPlaylist();
if (pl_manager.IsPlaylistLoaded() == false)
Console.WriteLine("Unloaded successfully");
}
else
{
if (File.Exists(playlistpath))
{
pl_manager.LoadPlaylist(playlistpath);
if (pl_manager.IsPlaylistLoaded() == false)
Console.WriteLine("Error in applying playlist:- {0}", playlistpath);
else
Console.WriteLine("Loaded playlist:- {0}", playlistpath);
}
else
{
Console.WriteLine("ERROR!Playlist file {0} not found!", playlistpath);
return pl_manager;
}
}
}
catch(Exception e)
{
Console.WriteLine("Exception:-{0}", e.ToString());
}
return pl_manager;
}

Multiple boolean checks or an invalids counter

What is your preferred way to implement actions based on the invalidity of multiple variables:
ie:
invalid_get() {
return a_invalid || b_invalid || c_invalid;
}
a_invalid_set(v) {
a_invalid=v;
if(v) {
validate_add();
} else {
validate_remove();
}
}
function validate_remove() {
if(!invalid_get()) {
validate_remove_do();
}
}
OR:
var invalids_num:Int;
function a_invalid_set(v) {
a_invalid=v;
if(v) {
++invalids_num;
validate_add();
} else {
--invalids_num;
validate_remove();
}
}
validate_remove() {
if(invalids_num==0) {
validate_remove_do();
}
}
I am guessing that a int check against 0 is faster and is without question the correct pattern, certainly for a large number of properties.

LedgerJournalEngine.errorExists(voucherNumber) not reporting errors

When attempting to validate a journal I use the LedgerJournalEngine ErrorExists for each voucher in the journal. For some reason it doesn't catch all errors in the code but if I use the validate button in the client the errors are in the info log.
Is there a better way to validate a voucher in a journal?
changecompany(ledgerJournalTable.dataAreaId)
{
ledgerJournalCheckPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::Yes,NoYes::No);
lje = LedgerJournalEngine::construct(ledgerJournalTable.JournalType);
lje.newJournalActive(ledgerJournalTable,true);
ledgerJournalCheckPost.parmLedgerJournalEngine(lje);
try
{
ledgerJournalCheckPost.run();
}
catch
{
ledgerJournalCheckPost.validate();
while select ledgerJournalTrans where ledgerJournalTrans.JournalNum == ledgerJournalTable.JournalNum
{
if(lje.errorExists(ledgerJournalTrans.Voucher))
{
errors.addError(lje.errorLog(ledgerJournalTrans.Voucher),ledgerJournalTrans.RecId);
}
}
}
}
So this is what I have come up with, so far it seems to be working as expected. If anyone has a better way please let me know.
changecompany(ledgerJournalTable.dataAreaId)
{
ledgerJournalCheckPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable,NoYes::No);
lje = LedgerJournalEngine::construct(ledgerJournalTable.JournalType);
lje.newJournalActive(ledgerJournalTable,true);
ledgerJournalCheckPost.parmLedgerJournalEngine(lje);
try
{
ledgerJournalCheckPost.run();
while select ledgerJournalTrans where ledgerJournalTrans.JournalNum == ledgerJournalTable.JournalNum
{
if(lje.errorInJournal() || ledgerJournalCheckPost.numOfErrorsInList()>0)
{
errors.addError(lje.errorLog(ledgerJournalTrans.Voucher),ledgerJournalTrans.RecId);
}
}
ledgerJournalCheckPost.parmPost(NoYes::Yes);
ledgerJournalCheckPost.run();
}
catch
{
ledgerJournalCheckPost.validate();
while select ledgerJournalTrans where ledgerJournalTrans.JournalNum == ledgerJournalTable.JournalNum
{
if(lje.errorInJournal() || ledgerJournalCheckPost.numOfErrorsInList()>0)
{
errors.addError(lje.errorLog(ledgerJournalTrans.Voucher),ledgerJournalTrans.RecId);
}
}
}
ledgerJournalCheckPost = null;
lje = null;
ledgerJournalTrans = null;
ledgerJOurnalTable = null;
}
return errors;

Find string in httpxml.responseText

Below is my code which I am trying to find 'Username Ok' in the respone text, and then flag UserNameOk as true. I cannot get this working.
function check_username(username)
{
var httpRequest;
make_request()
function stateck()
{
if(httpxml.readyState==4)
{
if (httpxml.responseText == "Username Ok")
{
UserNameOk = true;
}
else
{
UserNameOk = false;
}
checkCanSubmit();
document.getElementById("user_div").innerHTML=httpxml.responseText;
}
}
httpxml.onreadystatechange=stateck;
user_url="ajax_username.php?username=" + username.value;
httpxml.open("GET",user_url,true);
httpxml.send(null);
}
Below is my checkCanSubmit code
function checkCanSubmit()
{
if (UserNameOk && PasswordOk && EmailOk)
{
document.getElementById("button").disabled= false;
}
else
{
document.getElementById("button").disabled= true;
}
}
Any help will be appreciated Thanks.
Just a guess: the response might be something like "Username Ok\n" (the '\n' being a newline character which you can't see). Or it might have whitespace at the beginning or end. You could print out (alert) the length of the string to test that.
Are you seeing the correct response come in through firebug?
First step is to make sure your server is returning the correct response by looking at firebug. I might also simplify the code to help narrow down the issues. Try:
function check_username(username)
{
var httpRequest;
make_request()
function stateck()
{
if(httpxml.readyState==4)
{
if (httpxml.responseText == "Username Ok")
{
alert('1');
UserNameOk = true;
}
else
{
alert('2');
UserNameOk = false;
}
}
}
httpxml.onreadystatechange=stateck;
user_url="ajax_username.php?username=" + username.value;
httpxml.open("GET",user_url,true);
httpxml.send(null);
Can you be more specific about where the problem is?

Refactor nested IF statement for clarity [closed]

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 9 years ago.
Improve this question
I want to refactor this mumbo jumbo of a method to make it more readible, it has way to many nested IF's for my liking.
How would you refactor this?
public static void HandleUploadedFile(string filename)
{
try
{
if(IsValidFileFormat(filename)
{
int folderID = GetFolderIDFromFilename(filename);
if(folderID > 0)
{
if(HasNoViruses(filename)
{
if(VerifyFileSize(filename)
{
// file is OK
MoveToSafeFolder(filename);
}
else
{
DeleteFile(filename);
LogError("file size invalid");
}
}
else
{
DeleteFile(filename);
LogError("failed virus test");
}
}
else
{
DeleteFile(filename);
LogError("invalid folder ID");
}
}
else
{
DeleteFile(filename);
LogError("invalid file format");
}
}
catch (Exception ex)
{
LogError("unknown error", ex.Message);
}
finally
{
// do some things
}
}
I would reverse the conditions in the test to if bad then deleteAndLog as the example below. This prevent nesting and puts the action near the test.
try{
if(IsValidFileFormat(filename) == false){
DeleteFile(filename);
LogError("invalid file format");
return;
}
int folderID = GetFolderIDFromFilename(filename);
if(folderID <= 0){
DeleteFile(filename);
LogError("invalid folder ID");
return;
}
...
}...
Guard clauses.
For each condition, negate it, change the else block into the then block, and return.
Thus
if(IsValidFileFormat(filename)
{
// then
}
else
{
// else
}
Becomes:
if(!IsValidFileFormat(filename)
{
// else
return;
}
// then
If you are not against using exceptions, you could handle the checks without nesting.
Warning, air code ahead:
public static void HandleUploadedFile(string filename)
{
try
{
int folderID = GetFolderIDFromFilename(filename);
if (folderID == 0)
throw new InvalidFolderException("invalid folder ID");
if (!IsValidFileFormat(filename))
throw new InvalidFileException("invalid file format!");
if (!HasNoViruses(filename))
throw new VirusFoundException("failed virus test!");
if (!VerifyFileSize(filename))
throw new InvalidFileSizeException("file size invalid");
// file is OK
MoveToSafeFolder(filename);
}
catch (Exception ex)
{
DeleteFile(filename);
LogError(ex.message);
}
finally
{
// do some things
}
}
One possible approach is to have single if statements that check for when the condition isn't true. Have a return for each one of these checks. This turns your method into a sequence of 'if' blocks instead of a nest.
There's not a lot to refactor here, as you keep the 3 tests separately due to the fact that the error messages relate to the test performed. You could opt for having the test methods report back the error to log so you don't have them in the if/else tree, which could make things simpler abit as you then could simply test for an error and log it + delete the file.
In David Waters reply, I don't like the repeated DeleteFile LogError pattern. I would either write a helper method called DeleteFileAndLog(string file, string error) or I would write the code like this:
public static void HandleUploadedFile(string filename)
{
try
{
string errorMessage = TestForInvalidFile(filename);
if (errorMessage != null)
{
LogError(errorMessage);
DeleteFile(filename);
}
else
{
MoveToSafeFolder(filename);
}
}
catch (Exception err)
{
LogError(err.Message);
DeleteFile(filename);
}
finally { /* */ }
}
private static string TestForInvalidFile(filename)
{
if (!IsValidFormat(filename))
return "invalid file format.";
if (!IsValidFolder(filename))
return "invalid folder.";
if (!IsVirusFree(filename))
return "has viruses";
if (!IsValidSize(filename))
return "invalid size.";
// ... etc ...
return null;
}
It's the elses above that throw my eye. Here's an alternative, inside the try {}
You can make this even shorter by returning after MoveToSafeFolder (Even though you're returning the finally block will be executed.) Then you don't need to assign an empty string to errorMessage, and you don't need to check is errorString empty before deleting the file and logging the message). I didn't do it here because many find early returns offensive, and I'd agree in this instance, since having the finally block execute after the return is unintuitive for many people.
Hope this helps
string errorMessage = "invalid file format";
if (IsValidFileFormat(filename))
{
errorMessage = "invalid folder ID";
int folderID = GetFolderIDFromFilename(filename);
if (folderID > 0)
{
errorMessage = "failed virus test";
if (HasNoViruses(filename))
{
errorMessage = "file size invalid";
if (VerifyFileSize(filename))
{
// file is OK
MoveToSafeFolder(filename);
errorMessage = "";
}
}
}
}
if (!string.IsNullOrEmpty(errorMessage))
{
DeleteFile(filename);
LogError(errorMessage);
}
I would to something like this:
public enum FileStates {
MoveToSafeFolder = 1,
InvalidFileSize = 2,
FailedVirusTest = 3,
InvalidFolderID = 4,
InvalidFileFormat = 5,
}
public static void HandleUploadedFile(string filename) {
try {
switch (Handledoc(filename)) {
case FileStates.FailedVirusTest:
deletefile(filename);
logerror("Virus");
break;
case FileStates.InvalidFileFormat:
deletefile(filename);
logerror("Invalid File format");
break;
case FileStates.InvalidFileSize:
deletefile(filename);
logerror("Invalid File Size");
break;
case FileStates.InvalidFolderID:
deletefile(filename);
logerror("Invalid Folder ID");
break;
case FileStates.MoveToSafeFolder:
MoveToSafeFolder(filename);
break;
}
}
catch (Exception ex) {
logerror("unknown error", ex.Message);
}
}
private static FileStates Handledoc(string filename) {
if (isvalidfileformat(filename)) {
return FileStates.InvalidFileFormat;
}
if ((getfolderidfromfilename(filename) <= 0)) {
return FileStates.InvalidFolderID;
}
if ((HasNoViruses(filename) == false)) {
return FileStates.FailedVirusTest;
}
if ((VerifyFileSize(filename) == false)) {
return FileStates.InvalidFileSize;
}
return FileStates.MoveToSafeFolder;
}
How about this?
public static void HandleUploadedFile(string filename)
{
try
{
if(!IsValidFileFormat(filename))
{ DeleteAndLog(filename, "invalid file format"); return; }
if(GetFolderIDFromFilename(filename)==0)
{ DeleteAndLog(filename, "invalid folder ID"); return; }
if(!HasNoViruses(filename))
{ DeleteAndLog(filename, "failed virus test"); return; }
if(!!VerifyFileSize(filename))
{ DeleteAndLog(filename, "file size invalid"); return; }
// --------------------------------------------------------
MoveToSafeFolder(filename);
}
catch (Exception ex) { LogError("unknown error", ex.Message); throw; }
finally { // do some things }
}
private void DeleteAndLog(string fileName, string logMessage)
{
DeleteFile(fileName);
LogError(logMessage));
}
or, even better, ... this:
public static void HandleUploadedFile(string filename)
{
try
{
if(ValidateUploadedFile(filename))
MoveToSafeFolder(filename);
}
catch (Exception ex) { LogError("unknown error", ex.Message); throw; }
finally { // do some things }
}
private bool ValidateUploadedFile(string fileName)
{
if(!IsValidFileFormat(filename))
{ DeleteAndLog(filename, "invalid file format"); return false; }
if(GetFolderIDFromFilename(filename)==0)
{ DeleteAndLog(filename, "invalid folder ID"); return false; }
if(!HasNoViruses(filename))
{ DeleteAndLog(filename, "failed virus test"); return false; }
if(!!VerifyFileSize(filename))
{ DeleteAndLog(filename, "file size invalid"); return false; }
// ---------------------------------------------------------------
return true;
}
private void DeleteAndLog(string fileName, string logMessage)
{
DeleteFile(fileName);
LogError(logMessage));
}
NOTE: You shouldn't be catching and swallowing generic Exception without rethrowing it...

Resources