I'm working on a piece ColdFusion code to calculate the grade point average. How do I format (Round up) the GPA to one decimal place?
I tried using numberFormat but I did not get the result as expected. The GPA was being rounded to the nearest whole number. Ex. when "I have GPA 3.23, the function would round it up to 3.0, instead of 3.2.
<cfdump var = "#numberFormat(totalgpa, '.0')#">
Ex.
When I have GPA 3.23, the expected result should be 3.2;
When I have GPA 3.45, the expected result should be 3.5;
When I have GPA 3.98, the expected result should be 4.0;
I stopped trusting CF when it comes to rounding and number precision. Here is "the Java way":
<cfoutput>
#roundWithScale(3.23, 1)# = 3.2<br>
#roundWithScale(3.45, 1)# = 3.5<br>
#roundWithScale(3.98, 1)# = 4.0<br>
</cfoutput>
<cffunction name="roundWithScale" access="public" output="false" returnType="numeric">
<cfargument name="value" type="numeric" required="true">
<cfargument name="scale" type="numeric" default="2">
<cfargument name="rounding" type="string" default="ROUND_HALF_UP">
<cfset LOCAL.BigDecimal = createObject("java", "java.math.BigDecimal")>
<cfset LOCAL.value = createObject("java", "java.math.BigDecimal").init(
toString(ARGUMENTS.value)
)>
<cfreturn LOCAL.value.setScale(
javaCast("int", ARGUMENTS.scale),
LOCAL.BigDecimal[ARGUMENTS.rounding]
)>
</cffunction>
Related
I have two separate lists which are giving me the results, I want to convert those separate lists in one query, i did used listoquery from cflib , but it does only for 1, not for more queries.
How can i do it, any clue, can't use queryappend, because i am on lucee.
<cffunction name="listToQuery" access="public" returntype="query" output="false"
hint="Converts a list to a single-column query.">
<cfargument name="list" type="string" required="yes" hint="List to convert.">
<cfargument name="delimiters" type="string" required="no" default="," hint="Things that separate list elements.">
<cfargument name="column_name" type="string" required="no" default="column" hint="Name to give query column.">
<cfset var query = queryNew(arguments.column_name)>
<cfset var index = ''>
<cfloop list="#arguments.list#" index="index" delimiters="#arguments.delimiters#">
<cfset queryAddRow(query)>
<cfset querySetCell(query,arguments.column_name,index)>
</cfloop>
<cfreturn query>
</cffunction>
or i have a for loop
like this
https://trycf.com/gist/28e9f2b8ff2992e0dc9f78709a0d2041/lucee5?theme=monokai
<cfscript>
list1 = '1,2,3,4,5,6,7,8';
list2 = '5,5,5,5,7,7,4,4';
result = queryNew("");
queryAddListAsNewColumn(result, "id", list1);
queryAddListAsNewColumn(result, "name", list1);
queryAddListAsNewColumn(result, "cid", list2);
writeDump(result);
/*
* Adds the provided list to the query as a new column. Automatically expands query records.
*/
function queryAddListAsNewColumn(query, columnName, list) {
// prepare list data
LOCAL.data = listToArray(ARGUMENTS.list);
LOCAL.dataCount = arrayLen(LOCAL.data);
// add new column to query
queryAddColumn(ARGUMENTS.query, ARGUMENTS.columnName);
// expand query if list to add exceeds the current record count
LOCAL.rowDelta = (LOCAL.dataCount - ARGUMENTS.query.recordCount);
if (LOCAL.rowDelta > 0) {
queryAddRow(ARGUMENTS.query, LOCAL.rowDelta);
}
// add list data to each cell in the new column
for (LOCAL.i = 1; LOCAL.i <= LOCAL.dataCount; LOCAL.i++) {
querySetCell(ARGUMENTS.query, ARGUMENTS.columnName, LOCAL.data[LOCAL.i], LOCAL.i);
}
// returning isn't necessary because the passed query argument is a reference, return whatever suits your needs
return ARGUMENTS.query;
}
</cfscript>
Assuming the two lists have the same length, you can do something like this.
myQuery = QueryNew(dummy, varchar);
QueryAddColumn(myQuery, Column1, varchar, ListToArray(List1);
QueryAddColumn(myQuery, Column2, varchar, ListToArray(List2);
QueryDeleteColumn(myQuery, dummy);
trying to handle the list deletion but stuck on ts deletion process: here is my small gist which i am working on, any help appreciated
https://trycf.com/gist/aa3871e76db36ad446b770b9bbbb4cec/lucee5?theme=monokai
<cfset lstFirst = "1,2,3,4,5">
<cfset lstMiddle = "6,7,8,9,10">
<cfset lstLast = "11,12,13,14,15">
From the lstFirst I should be able to delete from reverse like 5,4,3,2,1 but i should not be able to
delete from middle of the very next item which is 2
From the lstMiddle if the middle one is 8, i should be able to delete 7,6 and so on or 9,10 but i should not be able to
delete 6,10 without deleting 7 and 9
From the lstLast which is complete reverse of the lstFirst where the last element is selected and i should be able to delete
from 14,13,12 onward but cannot delete from middle or from 11 onward, it must start its deletion from 14 or 15 backwards this is the way i am trying to make it work
**<cfoutput>
<cfset lstFirst = "1,2,3,4,5">
<cfset lstMiddle = "6,7,8,9,10">
<cfset lstLast = "11,12,13,14,15">
<!--- It's work all dynamic values for lstFirst like 1,2,3,4,5 OR 1,2,3,4,5,6,7,8,9,10 OR 1,2,3,4,5,6,7,8,9,10,11,12 etc.... --->
======= Delete all number from reverse and except very next item to middle ====
<cfset convertToArray = listtoarray(lstFirst)>
<cfset getRoundValue =round(arraylen(convertToArray)/2)>
<cfset findMidNextEle = ArraySlice(convertToArray,1,getRoundValue)>
<cfset LfirstMiddle = listgetat(lstFirst,listfind(lstFirst,listlast(arraytolist(findMidNextEle)))-1)>
<cfloop from="#listlen(lstFirst)#" to="1" index="i" step="-1">
<cfset listgetVal = listgetat(lstFirst,i)>
<cfif LfirstMiddle NEQ listgetVal >
<cfset lstFirst =listdeleteat(lstFirst,i)>
</cfif>
<br/><cfdump var="#lstFirst#" /><br/>
</cfloop>
=========== Delete 7,6 and so on or 9,10 and delete 6,10 without deleting 7 and 9 ================================= <br/>
<cfset lstMiddleMiddle = listfind(lstMiddle,listgetat(lstMiddle,listfind(lstMiddle,listlast(mid(lstMiddle,1,listlen(lstMiddle)))))) >
<cfloop from="1" to="#listlen(lstMiddle)#" index="j">
<cfset userList = listlen(lstMiddle)>
<cfif userList GT 3 >
<cfset lstMiddle1 = listdeleteat(lstMiddle,lstMiddleMiddle-1)>
<cfset lstMiddle2 = listdeleteat(lstMiddle1,lstMiddleMiddle)>
<cfset lstMiddleMiddle = listfind(lstMiddle2,listgetat(lstMiddle2,listfind(lstMiddle2,listlast(mid(lstMiddle2,1,listlen(lstMiddle2))))))>
<cfset lstMiddle = lstMiddle2>
<br/><cfdump var="#lstMiddle2#" /></br>
<cfelse>
<cfset lstMiddle3 = listdeleteat(lstMiddle2,1)>
<cfset lstMiddle4 = listdeleteat(lstMiddle3,2)>
<cfbreak/>
</cfif>
</cfloop>
enter code here
<cfdump var="#lstMiddle4#" /> <br/>
=============== Delete from reverse except last number ==========
<!--- It's will work for all dynamic values --->
<cfset LastEle = listlast(lstLast)>
<cfloop from="#listlen(lstLast)#" to="1" step="-1" index="k">
<cfset getCurrentValue = listgetat(lstLast,k)>
<cfif LastEle NEQ getCurrentValue>
<cfset lstLast =listdeleteat(lstLast,k)>
</cfif>
</br><cfdump var="#lstLast#" /><br/>
</cfloop>
</cfoutput>**
If I have a query result like this
type_name | count
-----------------
test1 | 5
test2 | 4
test4 | 7
How to output the count base on the value of the column type_name?
From the table the row value 'test3' doesn't exist, but it doesn't mean it wont exist later after a refresh.
With the below code I will only get the value but looping 3 times since test3 value doesn't exist.
<cfoutput name="query">
<table>
<tr><td><cfif query.type_name eq 'test1'>#query.count#</cfif></td></tr>
<tr><td><cfif query.type_name eq 'test2'>#query.count#</cfif></td></tr>
<tr><td><cfif query.type_name eq 'test3'>#query.count#</cfif></td></tr>
<tr><td><cfif query.type_name eq 'test4'>#query.count#</cfif></td></tr>
</cfoutput>
<cfset testResults = [0,0,0,0]>
<cfloop query="query">
<cfset testResults[right(query.type_name, 1)] = query.count>
</cfloop>
<table>
<cfloop array="#testResults#" index="count">
<td>#count#</td>
</cfloop>
</table>
You should see
5
4
0
7
If you need a more dynamic approach, you can transform your full query result (all columns) to an array of structs:
<!---
<!--- test data --->
<cfset query = queryNew("type_name,count", "VARCHAR,INTEGER")>
<cfset queryAddRow(query, 3)>
<cfset querySetCell(query, "type_name", "test1", 1)>
<cfset querySetCell(query, "count", "5", 1)>
<cfset querySetCell(query, "type_name", "test2", 2)>
<cfset querySetCell(query, "count", "4", 2)>
<cfset querySetCell(query, "type_name", "test4", 3)>
<cfset querySetCell(query, "count", "7", 3)>
--->
<!--- number of tests to list --->
<cfset expectedNumberOfRows = 4>
<!--- remember all columns while transforming query to array of structs --->
<cfset queryColumns = listToArray(query.columnList)>
<!--- initialize array of structs --->
<cfset testResults = arrayNew(1)>
<cfloop from="1" to="#expectedNumberOfRows#" index="i">
<cfset blankResult = structNew()>
<!--- initialize all columns for each row --->
<cfloop array="#queryColumns#" index="columnName">
<cfset blankResult[columnName] = "">
</cfloop>
<!--- default values for specific columns --->
<cfset blankResult["type_name"] = "test#i#">
<cfset blankResult["count"] = "0">
<cfset testResults.add(blankResult)>
</cfloop>
<!--- transfer cell values from each query row to array of structs --->
<cfset queryRowIndex = 1>
<cfloop query="query">
<!--- extract possible row index --->
<cfset testNumber = trim( reReplace(query.type_name, "[^0-9]*([0-9]+)$", "\1") )>
<!--- transfer cells --->
<cfif reFind("^[0-9]+$", testNumber)>
<cfloop array="#queryColumns#" index="columnName">
<cfset testResults[int(testNumber)][columnName] = query[columnName][queryRowIndex]>
</cfloop>
</cfif>
<cfset queryRowIndex++>
</cfloop>
<cfoutput>
<table>
<cfloop array="#testResults#" index="testResult">
<tr>
<td>#testResult.type_name#</td>
<td>#testResult.count#</td>
<!--- add additional columns if desired --->
</tr>
</cfloop>
</table>
</cfoutput>
I'm building a new application using Coldfusion as the business logic layer or controller in an MVC pattern and wanting to setup a binary search algorithm to handle username lookup on a registration function. Are there any documented instances of implementing a binary search algorithm in Coldfusion/sql?
Code Below. Note this is far from perfect.
Just a rough attempt at trying to translate the syntax into CFML
<cffunction name="binarySearchFunc" access="public" returntype="boolean">
<!--- Define array collection variable and target --->
<cfargument name="collection" type="array">
<cfargument name="target">
<!--- If the target is empty, return false --->
<cfif not isDefined(#argument.target#) or is Null>
<cfset returnValue = "false">
<cfreturn returnValue >
<!--- Else set the high, mid and low params for binary search --->
<cfelse>
<cfparam name="low" type="integer" default="0">
<cfparam name="high" type="integer" default="#ArrayLen(collection)#-1" >
<cfparam name="ix" type="integer" default="">
<cfscript>
While( low LTE high){
<!--- set the mid variable equal to the mean value between the low and
high --->
ix = (#low# + #high#)/2
<!--- set a variable equal to compareTo method of the target below --->
intVar = #target#.compareTo(collection[xi] <!--- equivalent CF syntax
??? --->
if (intVar LTE 0 ) {
//target value less than collection[i]
high = ix - 1;
}
else if (intVar GT 0 ){
low = ix ++ 1 ; }
else {
var returnValue = "true";
return returnValue;
}
}
</cfscript>
</cfif>
</cffunction>
The code below outputs weekend dates in the current month.
CODE:
<cfparam name="month" default="#DatePart('m', Now())#">
<cfparam name="year" default="#DatePart('yyyy', Now())#">
<cfset ThisMonthYear=CreateDate(year, month, '1')>
<cfset Days=DaysInMonth(ThisMonthYear)>
<cfset ThisDay = 1>
<cfloop condition="ThisDay LTE Days">
<cfset presentDay = CreateDate(year, month, thisday)>
<cfif DayOfWeek(presentDay) EQ '7'>
<cfoutput>#ThisDay#</cfoutput>
<cfelseif DayOfWeek(presentDay) EQ '1'>
<cfoutput>#ThisDay#</cfoutput>
</cfif>
<cfset ThisDay = ThisDay + 1>
</cfloop>
OUTPUT:
6 7 13 14 20 21 27 28
What I'm trying is to pass value of this cfloop in one variable. The code below only displays the last weekend date value.
CODE:
<cfset ThisDay = 1>
<cfset weekDayOfMonth = "">
<cfloop condition="ThisDay LTE Days">
<cfset presentDay = CreateDate(year, month, thisday)>
<cfif DayOfWeek(presentDay) EQ '7'>
<cfset weekDayOfMonth = ThisDay>
<cfelseif DayOfWeek(presentDay) EQ '1'>
<cfset weekDayOfMonth = ThisDay>
</cfif>
<cfset ThisDay = ThisDay + 1>
</cfloop>
<cfoutput>#weekDayOfMonth#</cfoutput>
OUTPUT
28
Question, what do I need fix in my last cfloop code so I can pass loop values into the jsWeekendDates variable?
Any help will be greatly appreciated.
Thank you.
Just figured on my own. Enjoy.
<cfset ThisDay = 1>
<cfset weekDay = "">
<cfloop condition='ThisDay LTE Days'>
<cfset presentDay = CreateDate(year, month, thisday)>
<cfif DayOfWeek(presentDay) EQ '1' OR DayOfWeek(presentDay) EQ '7'>
<cfset weekDay = weekDay & " " & ThisDay">
</cfif>
<cfset ThisDay = ThisDay + 1>
</cfloop>
<cfoutput>#weekDay#</cfoutput>