Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Min, Max TCL Command. 3

Status
Not open for further replies.

bebig

Technical User
Oct 21, 2004
111
US
is there any way to find minimum value or maximum value??
 
Code:
package require Tcl 8.2
package require math

then you get the following functions avalaible:
::math::cov value value ?value ...?
::math::integrate list of xy value pairs
::math::fibonacci n
::math::max value ?value ...?
::math::mean value ?value ...?
::math::min value ?value ...?
::math::prod value ?value ...?
::math::random ?value1? ?value2?
::math::sigma value value ?value ...?
::math::stats value value ?value ...?
::math::sum value ?value ...?
 
Extended Tcl, package TclX also has a min & max function as well.
 
thank you.

well, is there another way, not using TCL lib?


 
I guess what I'm hearing you say is that you don't want to deal with packages ... right?

Assuming you have a list of numbers, "nl" ...

In that case try something like this:

set mv 5000 ;#some large value
foreach x $nl {
if {$x < $mv} {
set mv $x
}
}
puts "Min value is : $mv"

... is that somehing you're looking for?
 
I want to find the earlist opened store.

for example,

File name is test.txt

lindex 0 lindex 1
--------------------
1 "10:03"
2 "09:40"
3 "11:10"
4 "08:40"

---code----

set readFile [open "test.txt" "r"]

gets $readFile line

while {![eof $readFile]} {

# write the line to the backup file "output this line to a file"
set lineList1 [string map {\" ""} $line]
set storeNum [lindex $lineList1 0]
set startTime [lindex $lineList1 1]
puts "$storeNum $startTime"
gets $readFile line
}

how to calculate the minimum value from startTime??
please help me~~
 
A little more consolidated code ...

set readFile [open "test.txt" "r"]

while {[gets $readFile line] >= 0} {
set lineList1 [string map {\" ""} $line];#removes Q's

foreach item $linelist1 {
lappend storeNum [lindex $item 0]
lappend startTime [lindex $item 1]
}
}
# Now once you have the two list (storeNum & startTime)
# you can do the following:

set mv 5000 ;#some large value
foreach x $startTime {
if {$x < $mv} {
set mv $x
}
}
puts "Min value is : $mv"


I've not actually tested this code; let me know if this works or you need additional help.
 
opps, I see a mistake already ...

I forgot to convert the startTime values to something useful before doing a comparison.

You can use the clock scan cmd in the preceeding lappend cmd.
Note: Also, by incorporating the clock scan cmd, you can remove the "string map" cmd - the clock scan cmd doesn't care if the double quotes are there or not, I believe.
 
when I ran this code

I got wrong result..

what does exactly lappend do??
 
Easier by far is just to sort the file contents after storingit in a tcl array since your file format is suited to that data type anyway. Given that you have a list already..

Code:
proc thislisttoarray {lst arrayname} {
global [subst -novariable $arrayname] 
array set [subst -novariable $arrayname] {}
            foreach {x y} $lst {set [subst -novariable $arrayname]($x) $y}
}

proc myqsort {arrayname min max {function "string compare"}} {
upvar $arrayname local

             if {$min > $max} {return}
             set m $min
             for {set x [expr $min + 1]} {$x <= $max} {incr x} {
                 if {[eval $function $local($x) $local($min)] < 0} {
                     swap local [incr m] $x
                 }
              }
swap local $min $m
myqsort local $min [expr $m - 1]
myqsort local [expr $m + 1] $max
return
}

proc swap {arr el1 el2} {
upvar 1 $arr locswap

  set sw $locswap($el1)
  set locswap($el1) $locswap($el2)
  set locswap($el2) $sw

return
}

So if we have a list that looks like this:
Code:
set lst {4 10:30 5 14:25 1 00:12 2 03:30 3 08:30}

We can do the following:
Code:
thislisttoarray $lst aname
parray aname
aname(1) = 00:12
aname(2) = 03:30
aname(3) = 08:30
aname(4) = 10:30
aname(5) = 14:25

As you can see I've already sorted this array ;).
If it wasn't we simply do:
Code:
myqsort aname 1 [array size aname]

And it is sorted. Then to retrieve the earliest opening
and latest opening stores is simply a matter of grabbing
the first and last array indexed values.



 
Thank you very much.^^
after I open a file, and selected some data from a file
I just need 1 10:10(open time) 16:00(close)
so..
first, to get 10:10 (open time)
I thought about compare each time and keep the smallest numer.
do you have any idea??
thank you in advance.

=== file1.txt=============
num open close
1 "10:10" "12:00"
1 "12:10" "14:00"
1 "14:10" "16:00"
2
=========code==================
set readFile [open "test.txt" "r"]

gets $readFile line

while {![eof $readFile]} {

# write the line to the backup file "output this line to a file"
set lineList1 [string map {\" ""} $line]
set storeNum [lindex $lineList1 0]
set startTime [lindex $lineList1 1]
set closeTime [lindex $lineList1 2]
puts "$storeNum $startTime $closeTime"
gets $readFile line
}











 
using the -index option of lsort, I think you can do what you want. Here is how -index works:
-index index
If this option is specified, each of the elements of list must itself be a proper Tcl sublist. Instead of sorting based on whole sublists, lsort will extract the index'th element from each sublist and sort based on the given element. The keyword end is allowed for the index to sort on the last sublist element, and end-index sorts on a sublist element offset from the end. For example,
lsort -integer -index 1 {{First 24} {Second 18} {Third 30}}

returns {Second 18} {First 24} {Third 30}, and

lsort -index end-1 {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}

returns {c 4 5 6 d h} {a 1 e i} {b 2 3 f g}. This option is much more efficient than using -command to achieve the same effect.
Now let's take your code from above and add some new lines:
Code:
set readFile [open "test.txt" "r"]

  gets $readFile line

  while {![eof $readFile]} {

    # write the line to the backup file "output this line to a file"
    set lineList1 [string map {\" ""} $line]
    set storeNum [lindex $lineList1 0]
    set startTime [lindex $lineList1 1]
    set closeTime [lindex $lineList1 2]
    puts "$storeNum $startTime $closeTime"      
[red]
    set lineList2 [split $lineList1 " "]; #make a proper list
    lappend storeList $lineList2; #list of lists
[/red]
    gets $readFile line
  }
[red]
#now work on storeList
set openList [lsort -index 1 $storeList]
puts "earliest opening time = [lindex $openList 0]
set closeList [lsort -index 2 -decreasing $storeList]
puts "latest closing time = [lindex $closeList 0]
[/red]

Does that work for you?

Bob Rashkin
rrashkin@csc.com
 
when I run your recommended code,
I got this result

1 10:10 12:00
1 12:10 14:00
1 14:10 16:00
2 13:10 15:00

earliest opening time = 1 {} {} {} 10:10 {} {} 12:00
latest closing time = 1 {} {} {} 10:10 {} {} 12:00

I tried lsort, but it did not work..

many errors teach me ...^^

thank you
 
oh..I got it..
I changed
#set lineList2 [split $lineList1 " "]; #make a proper list
lappend storeList $lineList1; #list of lists


the result looks like

1 10:10 12:00
1 12:10 14:00
1 14:10 16:00
2 13:10 15:00

earliest opening time = 1 10:10 12:00
latest closing time = 1 14:10 16:00

but I have a question why I cannot see this reslt
2 13:10 15:00



 
oh..sorry..it works perfect..Isee..
I add more data into text file

1 "10:10" "12:00"
1 "12:10" "14:00"
1 "14:10" "16:00"
2 "11:10" "13:00"
2 "14:10" "16:00"
2 "15:10" "17:00"
3 "11:20" "12:00"
3 "12:10" "13:00"
3 "14:10" "18:00"

this is code
====set readFile [open "bong.txt" "r"]

gets $readFile line

while {![eof $readFile]} {

# write the line to the backup file "output this line to a file"
set lineList1 [string map {\" ""} $line]
set storeNum [lindex $lineList1 0]
set startTime [lindex $lineList1 1]
set closeTime [lindex $lineList1 2]
puts "$storeNum $startTime $closeTime"

#set lineList2 [split $lineList1 " "]; #make a proper list
lappend storeList $lineList1; #list of lists

gets $readFile line
}

#now work on storeList
set openList [lsort -index 1 $storeList]
puts "earliest opening time = [lindex $openList 0]"
set closeList [lsort -index 2 -decreasing $storeList]
puts "latest closing time = [lindex $closeList 0]"


======

if I want to have

num 1's earliest time and lasted time
num 2's earliest time and lasted time
num 3's earliest time and lasted time

can I use for-loop??

what if I don't know exact numbers?
num1
num2
num3
....
num?

would you plesase recommand??

thank you
 
Hmmm. Not such a simple file format after all.
Good example of lsorts utility. A star for bong.
 
marsd, you gave me another good example.
you are also good helper
thanks
 
if I want to have

num 1's earliest time and lasted time
num 2's earliest time and lasted time
num 3's earliest time and lasted time

can I use for-loop??
I think I'd make a couple of sorting passes. First, lsort with -index 0. That will group all the stores by store number. Then go through the list with foreach and make a sublist for each store:
Code:
foreach elm $<listname> {
    switch [lindex $elm 0] {
     1 {lappend sublist1 $elm}
     2 {lappend sublist2 $elm}
        ...
    }
}
Now you can sort each sublist however you want to.

what if I don't know exact numbers?
num1
num2
num3
....
num?

This requires another loop around the switching:
1. set up a sublist name
2. set up a store number variable
3. for each element in the list (sorted by store number, or, index 0),
3a. if the store number has changed, get a new sublist name and lappend to that.
3b. if the store number has not changed, lappend to the current sublist.

Bob Rashkin
rrashkin@csc.com
 
1 10:10 12:00
1 12:10 14:00
1 14:10 16:00
2 11:10 13:00
2 14:10 16:00
2 15:10 17:00
3 11:20 12:00
3 12:10 13:00
3 14:10 18:00

earliest opening time 1 10:10 12:00
latest closing time 1 14:10 16:00

earliest opening time 2 11:10 13:00
latest closing time 2 15:10 17:00

earliest opening time 3 11:20 12:00
latest closing time 3 14:10 18:00

this is my result after I ran..

what if I want to have

num earliest opening time latest closing time
1 10:10 16:00
2 11:10 17:00
3 11:20 18:00

I am trying how to make this result.
could you give me any idea for this?

this is the code
----------------------
set readFile [open "bong.txt" "r"]

gets $readFile line

while {![eof $readFile]} {

# write the line to the backup file "output this line to a file"
set lineList1 [string map {\" ""} $line]
set storeNum [lindex $lineList1 0]
set startTime [lindex $lineList1 1]
set closeTime [lindex $lineList1 2]
puts "$storeNum $startTime $closeTime"

lappend storeList $lineList1; #list of lists

gets $readFile line
}

#now work on storeList
set openList [lsort -index 1 $storeList]
lappend openList1 $openList

puts "earliest opening time = [lindex $openList 0]"
set closeList [lsort -index 2 -decreasing $storeList]
puts "latest closing time = [lindex $closeList 0]"
puts "#######"
puts "$openList1"


#####--------###
foreach elm $storeList {
switch [lindex $elm 0] {
1 {lappend sublist1 $elm}
2 {lappend sublist2 $elm}
3 {lappend sublist3 $elm}
}
}
#--------num1
set openListA [lsort -index 1 $sublist1]
lappend openListA1 $openListA
puts "$openListA1"
puts "earliest opening time = [lindex $openListA 0]"
set closeListA [lsort -index 2 -decreasing $sublist1]
puts "latest closing time = [lindex $closeListA 0]"
#--------num2
set openListB [lsort -index 1 $sublist2]
puts "earliest opening time = [lindex $openListB 0]"
set closeListB [lsort -index 2 -decreasing $sublist2]
puts "latest closing time = [lindex $closeListB 0]"
#--------num3
set openList3 [lsort -index 1 $sublist3]
puts "earliest opening time = [lindex $openList3 0]"
set closeList3 [lsort -index 2 -decreasing $sublist3]
puts "latest closing time = [lindex $closeList3 0]"
#--------
puts "############"
puts "examples"
puts "$sublist1"
puts "$sublist2"
puts "$sublist3"

 
I got this answer
1 10:10 16:00
2 11:10 17:00
3 11:20 18:00

here is a code.
but if you have any good idea, please advise me.
if we don't know "num", let say 1000
can I use "while" loop?

Thank you all
---b.txt---
num open close
1 "10:10" "12:00"
1 "12:10" "14:00"
1 "14:10" "16:00"
2 "11:10" "13:00"
2 "14:10" "16:00"
2 "15:10" "17:00"
3 "11:20" "12:00"
3 "12:10" "13:00"
3 "14:10" "18:00"
-------------------
set readFile [open "b.txt" "r"]

gets $readFile line

while {![eof $readFile]} {

# write the line to the backup file "output this line to a file"
set lineList1 [string map {\" ""} $line]
set storeNum [lindex $lineList1 0]
set startTime [lindex $lineList1 1]
set closeTime [lindex $lineList1 2]
puts "$storeNum $startTime $closeTime"

lappend storeList $lineList1; #list of lists

gets $readFile line
}


puts "#######"

foreach elm $storeList {
switch [lindex $elm 0] {
1 {lappend sublist1 $elm}
2 {lappend sublist2 $elm}
3 {lappend sublist3 $elm}
}
}
#--------num1
set openListA [lsort -index 1 $sublist1]
set openA "[lindex $openListA 0]"
set openAindex1 [lindex $openA 0];#house number
set openAindex2 [lindex $openA 1];#earliest opening time
set closeListA [lsort -index 2 -decreasing $sublist1]
set closeA "[lindex $closeListA 0]"
set closeAindex1 [lindex $closeA 2];#earliest opening time
puts "The result A : $openAindex1 $openAindex2 $closeAindex1"


#--------num2
set openListB [lsort -index 1 $sublist2]
set openB "[lindex $openListB 0]"
set openBindex1 [lindex $openB 0];#house number
set openBindex2 [lindex $openB 1];#earliest opening time
set closeListB [lsort -index 2 -decreasing $sublist2]
set closeB "[lindex $closeListB 0]"
set closeBindex1 [lindex $closeB 2];#earliest opening time
puts "The result B : $openBindex1 $openBindex2 $closeBindex1"

#--------num3
set openListC [lsort -index 1 $sublist3]
set openC "[lindex $openListC 0]"
set openCindex1 [lindex $openC 0];#house number
set openCindex2 [lindex $openC 1];#earliest opening time
set closeListC [lsort -index 2 -decreasing $sublist3]
set closeC "[lindex $closeListC 0]"
set closeCindex1 [lindex $closeC 2];#earliest opening time
puts "The result C : $openCindex1 $openCindex2 $closeCindex1"
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top