Kotlin, println with prompts and getting user input - visual-studio

First Name
Last Name
Street Address
City
State - 2 digits in length
Zip - Integer 4 digits in length (minimum and maximum)
GPA (from 0.0 to 4.0)
Major - String
Teacher Class - overrides the student class
The main class should
Instantiate the student class and prompt the user to enter each of these properties
Print out the data from the instantiated class.
Instantiate the teacher class.
Print out the data from the instantiated class.
I'm new to Kotlin but this is what I have so far.
How do I prompt the user for each data point, get their input for each, and then print the user input out as a whole once all info is entered
Ideal output
First Name: ...
Last Name: ...
Then once all info is entered it prints the entirety of the info entered by user with prompts.
open class Student(first: String, last: String, street: String, city: String, state: String, zip: Int, gpa: Int, major: String)
{
var firstName : String?= first
var lastName : String?= last
var streetAddress: Int?= street
var city: String?= city
var state : String?=state
var zip:Int?=zip
var gpa: Int?=gpa
var major: String?=major
}
class Teacher (first: String):Student (first)
fun main() {

Related

How to update room database and How to get the insert status is working or completed?

The first:
I've got dataList from retrofit And insert Room Database.
I want to change dataList(Like insert a element). My Room Database can work because I used OnConflictStrategy.REPLACE. but when I delete dataList some elements, My Room Database can not delete elements.
Dao:
#Insert (onConflict = OnConflictStrategy.REPLACE)
suspend fun insertData(dataList : List<Data>)
Entity:
#Entity
data class Data(
#PrimaryKey val Id : Long,
val Fl : String,
val FlMc : String,
val Dm : String,
val Mc : String,)
ViewModel:
fun insertData(dataList: List<Data>) = viewModelScope.launch {
dataRepository.insertData(dataList)
}
//get data from server
fun getData():LiveData<List<Data>>
Activity:
dataViewModel.getData().observer(this){
dataViewModel.insertData(it)
}
How to resolve this situation except DELETE ALL THEN INSERT
The second:
I want to use a progressbar to indicate that I am inserting dataList
How to get the insert status is working or completed
If I understand correctly, you issue is that you cannot delete because you are building a DataList item but don't know the primary key value as it's generated.
As you haven't shown the DataList entity then assuming it is like:-
#Entity
data class DataList(
#PrimaryKey(autogenerate = true)
val id: Long,
val othercolumns: String
....
)
and if you change from suspend fun insertData(dataList : List<Data>) to suspend fun insertData(dataList : List<Data>): List<Long> (i.e. added the List as the result)
Then you have the values of the id column in the result. In the case above the value is the value of the id column.
If the #PrimaryKey is not an integer type e.g. a String then the long returned WILL NOT be the value of the primary key. It will be a special value known as the rowid.
In short using an integer with primary key makes the column an alias of the rowid. if not an integer primary key then it is not an alias BUT the rowid still exists.
You can still use the rowid to access a specific row as the rowid MUST be a unique value. e.g. (again assuming the above) you could have an #Query such as
#Query("SELECT * FROM the_datalist_table WHERE rowid=:rowid")
suspend fun getDataListById(rowid: Long)
Only of use if you know the rowid though.
You could get rowid's say by using
#Query("SELECT rowid FROM the_datalist_table WHERE othercolumns LIKE :something")
suspend fun getRowidOfSomeDataLists(something: String): List<Long>
still not of great use as the selection criteria would also be able to provide a list of Datalists.
Additional re the comment:-
How to use in viewModel or Activity?
As an example you could do something like :-
fun insertData(dataList: List<Data>) = viewModelScope.launch {
val insertedDataList: ArrayList<Data> = ArrayList()
val insertedIdList = dataRepository.insertData(dataList)
val notInsertedDataList: ArrayList<Data> = ArrayList()
for(i in 0..insertedIdList.size) {
if (insertedIdList[i] > 0) {
insertedDataList.add(
Data(
insertedIdList[i], //<<<<< sets the id as per the returned list of id's
dataList[i].Fl,
dataList[i].FlMc,
dataList[i].Dm,
dataList[i].Mc)
)
} else {
notInsertedDataList.add(
Data(
insertedIdList[i], //<<<<< sets the id as per the returned list of id's WILL BE -1 as not inserted
dataList[i].Fl,
dataList[i].FlMc,
dataList[i].Dm,
dataList[i].Mc
)
)
}
}
val notInsertedCount = notInsertedDataList.size
val insertedCount = insertedDataList.size
}
So you have :-
insertedDataList an ArrayList of the successfully inserted Data's (id was not -1) with the id set accordingly.
notInsertedDataList an ArrayList of the Data's that were not inserted (id was -1) id will be set to -1.
insertedCount an Int with the number inserted successfully.
notInsertedCount and Int with the number not inserted correctly.
DELETE ALL
To delete all rows, unless you extract all rows you can't use the convenience #Delete, as this works on being provided the Object (Data) and selecting the row to delete according to the primary key (id column).
The convenience methods #Delete, #Update, #Insert are written to generate the underlying SQL statement(s) bases upon the object (Entity) passed.
e.g. #Delete(data: Data) would generate the SQL DELETE FROM data WHERE id=?, where ? would be the value of the id field when actually run.
The simpler way to delete all columns is to use the #Query annotation (which handles SQL statements other than SELECT statements). So you could have.
#Query("DELETE FROM data")
fun deleteAllData()
note that this does not the return the number of rows that have been deleted.

How to make a searcher with uncertain number of inputs?

I have a structure where I create and store books as follows.
type Book struct {
Authors [] string
ISBN string
Countries [] string
Category string
}
type Books []Book
Then I define the values as follows.
test123 := Books{}
test123 = append(test123, Book{
Authors: []string{"Alice", "John", "Bob"},
Countries: []string{"CA", "US", "DE"},
ISBN: "1234567",
Category: "sci-fi",
})
test123 = append(test123, Book{
Countries: []string{"UK"},
Category: "comic book",
ISBN: "0001298",
})
test123 = append(test123, Book{
Authors: []string{"Alice", "Bob"},
Countries: []string{"UK"},
Category: "comic book",
ISBN: "0001298",
})
test123 = append(test123, Book{
ISBN: []string{"FR", "AU"},
Category: "sci-fi",
})
Not every Book structure has all defined elements. So some Book structure elements may not have an ISBN and/or a Countries value.
How can I search in such a structure? For example, I have DE as the Country value and then give Alice as the Author value. How can I write a code that can find and retrieve relevant elements when given the value of both Alice and DE?
UPDATE
#Cerise Limón and #gonutz I haven't asked the question exactly, I'm sorry. This code only works for DE and Alice values, not for other values. For other combinations, I have to write blocks of code that consist of if and else. In fact, regardless of the values I will give, I want to make the algorithm that finds values when I search in any slice structure. Is it possible?
Sample Scenario - 1:
I have DE value for Author for Alice Countries. I want to find the "slices" that contain these values in the Books struct.
Sample Scenario - 2:
I have 123456 for ISBN, FR for Countries, Bob for Authors. I want to find the "slices" that contain these values in the Books struct.
In other words, the type and number of values I will give as input can be different.
Just code up what you want to be able to search for, just if and for like this:
for _, b := range books {
hasDE := false
for _, c := range b.Countries {
if c == "DE" {
hasDE = true
}
}
isAlice := false
for _, a := range b.Authors {
if a == "Alice" {
isAlice = true
}
}
if hasDE && isAlice {
fmt.Println(b)
}
}

Group by multiple columns, then order results

I have a list of a class with several properties, I want to group by 5 of them and then order the results of the grouping by 5 different properties. The result should be a List().
Lets say (pseudocode-ish)....
public class cls()
string firstSTR {get;set;}
string secondSTR {get;set;}
string thirdSTR {get;set;}
string fourthSTR {get;set;}
string fifthSTR {get;set;}
List<cls> vals = new List<cls>();
var tmp = PopulateList(); // Here I would populate several hundred cls()
var unique = tmp.GroupBy(i => new {
i.firstSTR,
i.secondSTR,
i.thirdSTR,
i.fourthSTR,
i.fifthSTR
}).ToList().OrderBy (i => new {
i.firstSTR,
i.secondSTR,
i.thirdSTR,
i.fourthSTR).ToList();
I have very limited experience with Linq and I am not able to figure out why this does not work. The result of the first group by does not return a list of cls so I am not even sure how I can define what I want to order on. I hope that I have provided enough information to explain what I am trying to do. Thank you in advance.
----- EDIT -------
Here is what some example data might look like. I have included 10 columns of sample data however the there are more like 50 columns in the class.
Last5|First5|Add5|ZipCode|InsuranceName|Policy#|Group#|GroupName|SubscriberName|SubscriberAddress
SMITH|JOHN|123 M|99523|Medicare|POL123|GRP123|GRPNM|SMITH| JOHN|123 MAIN ST 99253
SMITH|JOHN|123 M|99523|Medicare|POL123|GRP123|GRPNM|SMITH| JOHN|123 MAIN ST 99253
SMITH|JOHN|123 M|99523|Commercial|POL456|GRP456|GRRNM|SMITH| JOHN|123 MAIN ST 99253
SMITH|MARY|992 W|99324|Medicare|POL789|GRP789|GRPNM|SMITH|MARY|992 WEST ST 99324
SMITH|MARY|992 W|99324|Commerical|POLXXY|GRPXXY|GRPNM|SMITH|MARY|992 WEST ST 99324
Above there are 5 records, delimited with pipe. The output data must be unique on the first 5 fields: Last5, First5, Add5, ZipCode, and Insurance name. Although I am looking to group on these first 5 columns I need all the data in the original class object populated in the result. My result data should look like this.
Last5|First5|Add5|ZipCode|InsuranceName|Policy#|Group#|GroupName|SubscriberName|SubscriberAddress
SMITH|JOHN|123 M|99523|Medicare|POL123|GRP123|GRPNM|SMITH| JOHN|123 MAIN ST 99253
SMITH|JOHN|123 M|99523|Commercial|POL456|GRP456|GRRNM|SMITH| JOHN|123 MAIN ST 99253
SMITH |MARY|992 W|99324|Medicare|POL789|GRP789|GRPNM|SMITH|MARY|992 WEST ST 99324
SMITH |MARY|992 W|99324|Commerical|POLXXY|GRPXXY|GRPNM|SMITH|MARY|992 WEST ST 99324
The result should only have 4 records as one Medicare Records for John Smith has been removed because the first 5 fields are a duplicate of another. Any other field in the remaining 5 columns (again, 50 or so in my data) can be the same, or different, it does not matter.
Im assuming that you don't want aggregates
var unique = tmp.GroupBy(i => new {
i.firstSTR,
i.secondSTR,
i.thirdSTR,
i.fourthSTR,
i.fifthSTR
}).Select(p=> new {
firstSTR = p.Key.firstSTR,
secondSTR = p.Key.secondSTR,
thirdSTR = p.Key.thirdSTR,
fourthSTR= p.Key.fourthSTR,
fifthSTR =p.Key.fifthSTR,
}).OrderBy(p=> p.firstSTR)
.ThenBy(p=> p.secondSTR)
.ThenBy(p=> p.thirdSTR)
.ThenBy(p=> p.fourthSTR)
.ThenBy(p=> p.fifthSTR)
.ToList();

Can not access objects properties

Let's say we have the following code:
class Person {
dynamic var name: String!
dynamic var age: Int = 30
}
let Bob = Person()
Bob.name = "Bob"
Bob.age = 60
println("\(Bob.name) is \(Bob.age) years old!") // Outputs Line1, seen below
let predicate = NSPredicate(format: "name = %#", "Bob")
let AClone = Person.objectsWithPredcate(predicate) // Searching for Person objects with name = Bob
println(AClone) // Outputs the Bob object
println(AClone.name) // Has Error1, seen below
The outputs are:
Line1: Bob is 60 years old!
The Errors are:
Error1: does not have a member named 'name'
This error is caused because technically AClone does not have a member named 'name' until after run time. Once the code has been run, AClone then has a member named 'name'. My question is, how do I tell Xcode that .name is a property that AClone will have after run-time? Is there a way for me to print AClone.name?
Note:
I have limited access to many sites due to my location in the world. Please excuse me if an answer to this already exists. If it does, please link to it and as soon as I can I'll take a look at the site.
Thanks!

Sorting a Wicket DataTable by a PropertyColumn that contains some null values

Here is some psuedo code for my table:
List<IColumn<Foo>> columns = new ArrayList<IColumn<Foo>>();
columns.add(new PropertyColumn<Foo>(Model.of("Name"), "name", "name"));
columns.add(new PropertyColumn<Foo>(Model.of("Leader"), "leader.lastName",
leader.fullName"));
fooTable = new AjaxFallbackDefaultDataTable<Foo>("fooTable", columns,
provider, 10);
The class Foo contains among other fields:
private String name;
private User leader;
And class User contains Strings userName, password, firstName, lastName, email, along with:
public String getFullName() {
// Use blank strings in place of "null" literals
String f = firstName != null ? firstName: "";
String l = lastName != null ? lastName: "";
return (l + ", " + f);
}
Every Foo has a name, and every User has has a first and last name. However, not every Foo has a leader, so in the table above, there are several null/ blank values for leader. When the table is sorted by leader by clicking the column header, all Foo's without a leader are missing. When sorted again by name, they return, with blanks for leader.
Is there anyway to fix this? A preference where nulls always sort last would be best, but I'll take anything where they don't just disappear.
The correct sorting is a responsibility of the SortableDataProvider. If it is making items disappear, you should revise it's logic.

Resources