Exporting to text in xojo - listbox

I want to export data from a listbox,
Listbox1.AddRow "001", "Orange", "1.00","Arief"
Listbox1.AddRow "001", "Apple", "1.00","Arief"
Listbox1.AddRow "001", "Banana", "1.00","Arief"
Listbox1.AddRow "004", "Orange", "1.00","Arief"
Listbox1.AddRow "005", "Apple", "1.00","Brandon"
Listbox1.AddRow "006", "Banana", "1.00","Brenda"
dim f as folderitem
dim tisx as TextOutputStream
f = new folderitem("item.txt")
tisx = f.CreateTextFile
dim Last_first_word as String
dim maxRow as Integer = Listbox1.listcount-1
for row as integer = 0 to maxRow
if Listbox1.Cell(row,0)<> Last_first_word then
tisx.WriteLine ""
tisx.writeline listBox1.cell(row,0)
tisx.WriteLine listBox1.cell(row,1)+" "+listBox1.cell(row,2)
Last_first_word=Listbox1.Cell(row,0)
else
tisx.WriteLine listBox1.cell(row,1)+" "+listBox1.cell(row,2)
end if
next
tisx.Close
I want to categorized all the items which is has the same code,and put the name at the last.
How to make the result like ,
001
Orange 1.00
Apple 1.00
Banana 1.00
Arief
004
Orange 1.00
Arief
005
Apple 1.00
Brandon
006
Banana 1.00
Brenda
Thanks
Regards,
Arief

You'll need to also save the name so you can display it before you move onto a new group of data. Only a minor tweak to your code was needed:
Listbox1.DeleteAllRows
ListBox1.AddRow("001", "Orange", "1.00", "Arief")
ListBox1.AddRow("001", "Apple", "1.00", "Arief")
ListBox1.AddRow("001", "Banana", "1.00", "Arief")
ListBox1.AddRow("004", "Orange", "1.00", "Arief")
ListBox1.AddRow("005", "Apple", "1.00", "Brandon")
ListBox1.AddRow("006", "Banana", "1.00", "Brenda")
Dim f As FolderItem
Dim tisx As TextOutputStream
f = SpecialFolder.Desktop.Child("item.txt")
tisx = f.CreateTextFile
Dim Last_first_word As String
Dim lastName As String
Dim maxRow As Integer = Listbox1.ListCount - 1
For row As Integer = 0 To maxRow
If Listbox1.Cell(row, 0) <> Last_first_word Then
If lastName <> "" Then tisx.WriteLine(lastName)
tisx.WriteLine("")
tisx.WriteLine(ListBox1.Cell(row, 0))
tisx.WriteLine(ListBox1.Cell(row, 1) + " " + ListBox1.Cell(row, 2))
Last_first_word = ListBox1.Cell(row, 0)
lastName = ListBox1.Cell(row, 3)
Else
tisx.WriteLine(ListBox1.Cell(row, 1) + " " + ListBox1.Cell(row, 2))
End If
Next
If lastName <> "" Then tisx.WriteLine(lastName)
tisx.Close
The data has to be sorted by that group number in order for this to work.

Related

Lua Table - Search for Items that starts with an Letter

i have this table
animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324
}
there i can search by a listed entry
for _,v in pairs(animals) do
if v.sname == "bunny" then
print(v.sname, v.name, v.size, v.size2, v.size3)
break
end
end
and get the result:
bunny bunny hase 4 8 9
Now i want to search in my table by starting with a single Letter, for example "b", that show me all the entries starting with the letter "b" to get the same result?
I found no Solution. May you can help me?
First: The table animals needs a trailing } ;-)
Put it in a Lua -i console and play around with...
>animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324}
}
-- Now set a __call metamethod on same table
>setmetatable(animals,{__call=function(tab,...)
local args={...}
for key, value in pairs(tab) do
if value.sname:find(args[1],1) then print(key,'=',value.sname) end
end
end})
table: 0x565c4a00
-- Lets try it once
>animals('b')
1 = bunny
-- Next one
>animals('c')
3 = cow
-- Last one
>animals('m')
2 = mouse
Using metatables holds your stuff together.
Another fine place is the __index metamethod that can hold all functions you need for that table and can be used like the string functions on a string.
( Like: value.sname:find(args[1],1) )
This leads to the heart of what find should do.
In first example it looks in whole sname for a matching pattern.
Check the Lua patterns what also can be useful.
Maybe a ^ only for the begining sounds smart?
So construct the find pattern: '^'..args[1]
...and use more than one letter if you have a cow, crow, frog and fish in your animals.
Example with function name find in __index
>animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324}
}
-- Place a find function into __index
>setmetatable(animals,{__index={find=function(tab,...)
local args={...}
for key, value in pairs(tab) do
if value.sname:find('^'..args[1]) then print(key,'=',value.sname) end
end
end}})
table: 0x565c3db0
-- first
>animals:find('c')
3 = cow
-- next
>animals:find('m')
2 = mouse
-- last
>animals:find('b')
1 = bunny
If you like to print all key values then extend the print() in find().
Stop, i found an issue....
Look here - i prefer the first solution:
animals = {
{sname = "bunny", name = "bunny hase", size = 4, size2 = 8, size3 = 9},
{sname = "mouse", name = "Micky Mouse", size = 1, size2 = 12, size3 = 22},
{sname = "cow", name = "Die Kuh", size = 30, size2 = 33, size3 = 324}
}
-- Now set a __call metamethod on same table
setmetatable(animals,{__call=function(tab,...)
local args={...}
for v,k in pairs(tab) do
if k.sname:find(args[1],1) then print(v,'=',k.sname) end
end
end})
-- Search Entries with Start U.....
-- there should be no result, but....
animals('u')
i get the Result:
1 = bunny
2 = mouse
that should not be the result!

ggplotly tooltip is showing data twice

I have 2 datasets included in one chart using ggplot. I am using ggplotly to create a tooltip but the information in the tooltips for the 2 points is showing twice. The following code is a little lengthy but will recreate the chart:
AreaName <- c("A", "B", "C", "A", "B", "C")
Timeperiod <- c("2018", "2018", "2018", "2019", "2019", "2019")
Value <- c(11.5, 39.3, 9.4, 14.2, 40.7, 19.1)
df <- data.frame(cbind(AreaName, Timeperiod, Value), stringsAsFactors = F)
df$Value <- as.numeric(df$Value)
AreaName <- c("A", "A")
Timeperiod <- c("2019", "2020")
qtr <- c("Q1-Q2", "Q1-Q2")
Value <- c(15.6, 10.2)
df2 <- data.frame(cbind(Timeperiod, qtr, AreaName, Value), stringsAsFactors = F)
df2$Value <- as.numeric(df2$Value)
ggp <- ggplotly(ggplot(data = df, aes(x=Timeperiod, y=Value, group = AreaName, colour = AreaName, text = paste("Area name: ", AreaName, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000"))) +
geom_line() +
geom_point() +
geom_point(data = df2, aes(shape = c(paste(AreaName, qtr, Timeperiod)),text = paste("Area name: ", AreaName, "<br>Quarter: ", qtr, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000"))) +
scale_shape_manual(values = c(18, 17)) +
theme(axis.text.x = element_text(vjust = 0.5), axis.title.x = element_blank()) +
labs(y = "Crude rate per 100,000 persons all ages", colour = "Area", shape = "") +
guides(shape = guide_legend(order = 2),colour = guide_legend(order = 1)) +
expand_limits(y=0), tooltip = "text")
ggpNames <- unique(df$AreaName)
legs <- paste(df2$AreaName, df2$qtr, df2$Timeperiod)
ggpNames <- c(ggpNames,legs)
for (i in 1:length(ggp$x$data)) { # this goes over all places where legend values are stored
n1 <- ggp$x$data[[i]]$name # and this is how the value is stored in plotly
n2 <- " "
for (j in 1:length(ggpNames)) {
if (grepl(x = n1, pattern = ggpNames[j])) {n2 = ggpNames[j]} # if the plotly legend name contains the original value, replace it with the original value
}
ggp$x$data[[i]]$name <- n2 # now is the time for actual replacement
if (n2 == " ") {ggp$x$data[[i]]$showlegend = FALSE} # sometimes plotly adds to the legend values that we don't want, this is how to get rid of them, too
}
ggp %>% config(displaylogo = FALSE, modeBarButtonsToRemove = list("autoScale2d", "resetScale2d","select2d", "lasso2d", "zoomIn2d", "zoomOut2d", "toggleSpikelines", "zoom2d", "pan2d"))
ggp
Does anyone have an elegant solution to this?
Thanks
Do not define text in geom_point for the second dataframe df2. Then you will get only one tooltip for those two points.
ggp <- ggplotly(ggplot(data = df, aes(x=Timeperiod, y=Value, group = AreaName, colour = AreaName, text = paste("Area name: ", AreaName, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000"))) +
geom_line() +
geom_point() +
geom_point(data = df2, aes(shape = c(paste(AreaName, qtr, Timeperiod)) #,
#text = paste("Area name: ", AreaName, "<br>Quarter: ", qtr, "<br>Time period: ", Timeperiod, "<br>Rate: ", round(Value,1), "per 100,000")
)) +
scale_shape_manual(values = c(18, 17)) +
theme(axis.text.x = element_text(vjust = 0.5), axis.title.x = element_blank()) +
labs(y = "Crude rate per 100,000 persons all ages", colour = "Area", shape = "") +
guides(shape = guide_legend(order = 2),colour = guide_legend(order = 1)) +
expand_limits(y=0), tooltip = "text")
ggpNames <- unique(df$AreaName)
legs <- paste(df2$AreaName, df2$qtr, df2$Timeperiod)
ggpNames <- c(ggpNames,legs)
for (i in 1:length(ggp$x$data)) { # this goes over all places where legend values are stored
n1 <- ggp$x$data[[i]]$name # and this is how the value is stored in plotly
n2 <- " "
for (j in 1:length(ggpNames)) {
if (grepl(x = n1, pattern = ggpNames[j])) {n2 = ggpNames[j]} # if the plotly legend name contains the original value, replace it with the original value
}
ggp$x$data[[i]]$name <- n2 # now is the time for actual replacement
if (n2 == " ") {ggp$x$data[[i]]$showlegend = FALSE} # sometimes plotly adds to the legend values that we don't want, this is how to get rid of them, too
}
ggp %>% config(displaylogo = FALSE, modeBarButtonsToRemove = list("autoScale2d", "resetScale2d","select2d", "lasso2d", "zoomIn2d", "zoomOut2d", "toggleSpikelines", "zoom2d", "pan2d"))
ggp

String format like a table in a loop swift4

I have this problem and all possible solutions I'm looking for online hasn't helped me. Is there a way to make a table like in a string format?
What I'm expecting the output will be like this for a string:
Category
ITEM1 QTY PRICE TOTAL
ITEM2 QTY PRICE TOTAL
but my output code is like this:
Category
ITEM1 QTY PRICE TOTAL
ITEM2 QTY PRICE TOTAL
Category
ITEM1 QTY PRICE TOTAL
ITEM2 QTY PRICE TOTAL
I figured out something that the item string length is the cost why they are not aligned formally in my format, but is there a way on how to solve this issue? I'm totally new in swift.
here is my code:
for category in self.categoryList {
sentence += "Category: \(category)\n"
for items in self.productList {
if category == items.category {
grandTotal += Double(items.qty)! * Double(items.price)!
let total: Double = Double(items.qty)! * Double(items.price)!
let item = (items.item as NSString).utf8String
let qty = (items.qty as NSString).utf8String
let price = (items.price as NSString).utf8String
sentence += String(format: "%-10s%20s%15s%15.02f\n", item!, qty!, price!, total)
}
}
sentence += "\n\n"
grandTotal = 0
}
lblData.text = sentence
You could pad your strings to a defined length:
let elements = ["ITEM1", "QTY", "PRICE", "TOTAL"]
// without padding
var sentence = ""
for e in elements {
if !sentence.isEmpty {
sentence += " "
}
sentence += e
}
print(sentence)
// prints "ITEM1 QTY PRICE TOTAL"
// with padding
sentence = ""
for e in elements {
sentence += e.padding(toLength: 10, withPad: " ", startingAt: 0)
}
print(sentence)
// prints "ITEM1 QTY PRICE TOTAL "
Or in a shorter form:
// without padding
var sentence = elements.joined(separator: " ")
print(sentence)
// with padding
sentence = elements.map({$0.padding(toLength: 10, withPad: " ", startingAt: 0)}).joined(separator: " ")
print(sentence)

How to feed a dictionary to a Flux model in Julia

So I have a 20000x4 dataset, where the 4 columns have strings. The first is a description and the other three are categories, the last one being the one I wish to predict. I tokenized every word of the first column and saved it in a dictionary, with his respective Int value, and I changed the other columns to have numerical values. Now I'm having trouble to understand how to feed these data in a Flux model.
According to the documentation, I have to use a "collection of data to train with (usually a set of inputs x and target outputs y)". In the example, it separates the data x and y. But how can I make that with a dictionary plus two numeric columns?
Edit:
Here is a minimal example of what I have right now:
using WordTokenizers
using DataFrames
dataframe = DataFrame(Description = ["It has pointy ears", "It has round ears"], Size = ["Big", "Small"], Color = ["Black", "Yellow"], Category = ["Dog", "Cat"])
dict_x = Dict{String, Int64}()
dict_y = Dict{String, Int64}()
function words_to_numbers(data, column, dict)
i = 1
for row in range(1, stop=size(data, 1))
array_of_words = tokenize(data[row, column])
for (index, word) in enumerate(array_of_words)
if haskey(dict, word)
continue
else
dict[word] = i
i += 1
end
end
end
end
function categories_to_numbers(data, column, dict)
i = 1
for row in range(1, stop=size(data, 1))
if haskey(dict, data[row, column])
continue
else
dict[data[row, column]] = i
i += 1
end
end
end
words_to_numbers(dataframe, 1, dict_x)
categories_to_numbers(dataframe, 4, dict_y)
I want to use dict_x and dict_y as my input and output for a Flux model
Consider this example:
using DataFrames
df = DataFrame()
df.food = rand(["apple", "banana", "orange"], 20)
multiplier(fruit) = (1 + (0.1 * rand())) * (fruit == "apple" ? 95 :
fruit == "orange" ? 45 : 105)
foodtoken(f) = (fruit == "apple" ? 0 : fruit == "orange" ? 2 : 3)
df.calories = multiplier.(df.food)
foodtoken(f) = (fruit == "apple" ? 0 : fruit == "orange" ? 2 : 3)
fooddict = Dict(fruit => (fruit == "apple" ? 0 : fruit == "orange" ? 2 : 3)
for fruit in df.food)
Now we can add the token numeric values to the dataframe:
df.token = map(x -> fooddict[x], df.food)
println(df)
Now you should be able to run the prediction with df.token as an input and df.calories as an output.
========== addendum after you posted further code: ===========
With your modified example, you just need a helper function:
function colvalue(s, dict)
total = 0
for (k, v) in dict
if occursin(k, s)
total += 10^v
end
end
total
end
words_to_numbers(dataframe, 1, dict_x)
categories_to_numbers(dataframe, 4, dict_y)
dataframe.descripval = map(x -> colvalue(x, dict_x), dataframe.Description)
dataframe.catval = map(x -> colvalue(x, dict_y), dataframe.Category)
println(dataframe)

Teechart + Word Wrap for legend

I am drawing a Trend chart(line) but in my case the legend Text is really big so it there any way that I can word wrap the text.
I think you can use the string functions that you can find in this link to manipulate the titles of series and try to reduce their length. I have made a suggestion code that I think can help you achieve as you want:
Private Sub Form_Load()
TChart1.Aspect.View3D = False
TChart1.AddSeries scLine
TChart1.AddSeries scLine
Dim i As Integer
TChart1.Series(0).AddXY 0, 30, "", clTeeColor
TChart1.Series(0).AddXY 10, 100, "", clTeeColor
TChart1.Series(1).AddXY 0, 50, "", clTeeColor
TChart1.Series(1).AddXY 50, 120, "", clTeeColor
TChart1.Series(0).Title = "DDDDAAAAFFFFLLLLRRRRSSSS"
TChart1.Series(1).Title = "AAAALLLLSSSSTTTTEEEERRRR"
SeriesTitleWarp TChart1.SeriesCount
End Sub
Private Sub SeriesTitleWarp(ByVal count As Long)
'Replace some chars of string title to ...
Dim i As Integer
For i = 0 To count - 1
'Calculate the size of string
Dim LenString As Integer
LenString = Len(TChart1.Series(i).Title)
'First replace the Left chars for ...
Dim TitleString As String
TitleString = TChart1.Series(i).Title
Mid$(TitleString, 10, 3) = "..."
'After cut the string
TitleString = Left(TitleString, 12)
'Assign new title to series.
TChart1.Series(i).Title = TitleString
Next i
End Sub
Revising your requirements, I suggest you an other alternative that reduces the Legend Text, but the title of series remains intact. Could you please check if next code works as you want?
Private Sub Form_Load()
TChart1.Aspect.View3D = False
TChart1.AddSeries scLine
TChart1.AddSeries scLine
Dim i As Integer
TChart1.Series(0).AddXY 0, 30, "", clTeeColor
TChart1.Series(0).AddXY 10, 100, "", clTeeColor
TChart1.Series(1).AddXY 0, 50, "", clTeeColor
TChart1.Series(1).AddXY 50, 120, "", clTeeColor
TChart1.Series(0).Title = "DDDDAAAAFFFFLLLLRRRRSSSS"
TChart1.Series(1).Title = "AAAALLLLSSSSTTTTEEEERRRR"
' TChart1.Legend.ShapeBounds.Right = 100
TChart1.Legend.Left = 100
TChart1.Legend.CustomPosition = True
TChart1.Legend.Width = 100
End Sub
Private Sub TChart1_OnGetLegendText(ByVal LegendStyle As Long, ByVal ValueIndex As Long, LegendText As String)
If ValueIndex <> -1 Then
'Calculate the size of string
Dim LenString As Integer
LenString = Len(TChart1.Series(ValueIndex).Title)
'First replace the Left chars for ...
Dim TitleString As String
TitleString = TChart1.Series(ValueIndex).Title
Mid$(TitleString, 10, 3) = "..."
'After cut the string
TitleString = Left(TitleString, 12)
'Assign new text to LegendText
LegendText = TitleString
End If
End Sub
I hope will helps.
Thanks.

Resources