问:
Android search query returning null list
For my app I am using an sqllite database to make a movie logging app. A movie object has the title, a boolean for whether the user has already seen the movie or not and whether they have it on their watchlist

I am able to add a movie to the sqllite database, but when I run a search query to return a list of Movie object, I try get a null pointer exception when I try to display the results in a Listview.

This is my movie object's variable types

```<code>public class Movie implements Serializable {
private String movieTitle;
private boolean seen; //true if user has seen movie
private boolean addToWatchlist; //if user wants to add movie to watchlist
</code>```

This is my table and ts fields

```<code>@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_MOVIE_TABLE = "CREATE TABLE " + MOVIE_TABLE + "("
            + KEY_ID + " INTEGER PRIMARY KEY," + KEY_TITLE + " TEXT,"
            + KEY_SEEN + " INT," + KEY_WATCHLIST + " INT " + ")";
    db.execSQL(CREATE_MOVIE_TABLE);
}
</code>```

My addMovie method

```<code>public void addMovie(Movie m) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(KEY_TITLE, m.getmMovieTitle());

    if (m.isSeen()) {
        values.put(KEY_SEEN, 1);
    }
    else {values.put(KEY_SEEN,0);}

    if (m.isAddWatchlist()) {
        values.put(KEY_WATCHLIST, 1);
    }
    else {values.put(KEY_WATCHLIST,0);}
    System.out.println(values.toString());

    db.insert(MOVIE_TABLE, null, values);
    db.close();
</code>```

And the Select Query which is the source  of all my problems. Resulting in a null list even after adding movies that have been seen, where I set seen = 1;

```<code>public ArrayList<Movie> getSeenMovies(){
    ArrayList<Movie> seenList = new ArrayList<Movie>();
    String selectQuery = "SELECT * FROM " + MOVIE_TABLE + " WHERE " + KEY_SEEN + " == " +1;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    if (cursor != null && cursor.moveToFirst()) {
        do {
            Movie m = new Movie();
            m.setMovieTitle(cursor.getString(1));
            m.setSeen(true);

            m.setAddWatchlist(Integer.parseInt(cursor.getString(3)) == 1);

            seenList.add(m);
        }
        while (cursor.moveToNext());
    }
    return seenList;
}
</code>```

The NullPointerException comes when I try to populate my listview with the query results because of the movieList.size() in the getCount method of my MovieArrayAdapter class which says my movieList is null

MovieArrayAdapter

```<code>public class MovieArrayAdapter extends BaseAdapter {

private Context context;
private ArrayList<Movie> movieList;

//adapter constructor
public MovieArrayAdapter(Context context, ArrayList<Movie> movieList) {
    this.context = context;
    this.movieList = movieList;
}

//abstract method returns size of movie list
public int getCount() {
        return this.movieList.size();
}

//abstract method returns item at input position in list
public Object getItem(int pos){return this.movieList.get(pos);}

// abstract method gets item id at position i
public long getItemId(int pos){return pos;}

public View getView(int position, View convertView, ViewGroup parent){

    View v = View.inflate(context, R.layout.movie_list_entry, null);

    //finds MovieTitle textview field in the movie_list entry layout file
    TextView title = (TextView)v.findViewById(R.id.MovieTitle);

    //sets MovieTitle field to title of movie from list
    title.setText(movieList.get(position).getmMovieTitle());

    return v;}
}
</code>```

The error:

```<code>E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.indiana.kupshah.movdex, PID: 4754
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.indiana.kupshah.movdex/com.indiana.kupshah.movdex.SeenList}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                  at android.app.ActivityThread.-wrap12(ActivityThread.java)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
                  at com.indiana.kupshah.movdex.MovieArrayAdapter.getCount(MovieArrayAdapter.java:32)
                  at android.widget.ListView.setAdapter(ListView.java:493)
                  at com.indiana.kupshah.movdex.SeenList.onCreate(SeenList.java:27)
                  at android.app.Activity.performCreate(Activity.java:6662)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                  at android.app.ActivityThread.-wrap12(ActivityThread.java)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
</code>```

DBHandler movdexDB = new DBHandler(this); is an instance variable for the add movie form

This adds movie to the db when add button is clicked

```<code>public void onAddButtonClick(View v){
    EditText movieTitle = (EditText) findViewById(R.id.TitleText);
    CheckBox seen = (CheckBox) findViewById(R.id.SeenCheck);
    CheckBox watch = (CheckBox) findViewById(R.id.WatchCheck);

    //converts View values to types suitable for Movie class
    String addTitle = movieTitle.getText().toString();
    Boolean addSeen = seen.isChecked();
    Boolean addWatch = watch.isChecked();

    Movie movie = new Movie (addTitle,addSeen,addWatch);

    movdexDB.addMovie(movie);
}
</code>```

This is the button click that starts the SeenList Activity

```<code>public void onSeenButtonClick(View v){
    Intent myIntent = new Intent(AddMovieEntry.this,SeenList.class);
    myIntent.putExtra("seen_list", movdexDB.getSeenMovies());
    startActivity(myIntent);
}
</code>```

And lastly, the SeenList onCreate method

```<code>protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_seen_list);

    //finds list view and populates from movies from the seen list,
    //using the layout established in the MovieAdapter arrayadapter class
    ListView SeenListView = (ListView) findViewById(R.id.SeenList);

    Intent i = getIntent();
    ArrayList<Movie> seenList;
    //sets the list of seen and watched movies
    seenList = (ArrayList<Movie>) i.getSerializableExtra("seenlist_movies");
    MovieArrayAdapter myAdapter = new MovieArrayAdapter(this, seenList);
    SeenListView.setAdapter(myAdapter);
}
</code>```

答:
Looks like you just need to protect access for null values in MovieArrayAdapter:</p>

```<code>public int getCount(){
  return movieList != null ? movieList.size() : 0;
}
</code>```

Body:
For my app I am using an sqllite database to make a movie logging app. A movie object has the title, a boolean for whether the user has already seen the movie or not and whether they have it on their watchlist

I am able to add a movie to the sqllite database, but when I run a search query to return a list of Movie object, I try get a null pointer exception when I try to display the results in a Listview.

This is my movie object's variable types

public class Movie implements Serializable {
private String movieTitle;
private boolean seen; //true if user has seen movie
private boolean addToWatchlist; //if user wants to add movie to watchlist

This is my table and ts fields

@Override
public void onCreate(SQLiteDatabase db) {
    String CREATE_MOVIE_TABLE = "CREATE TABLE " + MOVIE_TABLE + "("
            + KEY_ID + " INTEGER PRIMARY KEY," + KEY_TITLE + " TEXT,"
            + KEY_SEEN + " INT," + KEY_WATCHLIST + " INT " + ")";
    db.execSQL(CREATE_MOVIE_TABLE);
}

My addMovie method

public void addMovie(Movie m) {
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(KEY_TITLE, m.getmMovieTitle());

    if (m.isSeen()) {
        values.put(KEY_SEEN, 1);
    }
    else {values.put(KEY_SEEN,0);}

    if (m.isAddWatchlist()) {
        values.put(KEY_WATCHLIST, 1);
    }
    else {values.put(KEY_WATCHLIST,0);}
    System.out.println(values.toString());

    db.insert(MOVIE_TABLE, null, values);
    db.close();

And the Select Query which is the source  of all my problems. Resulting in a null list even after adding movies that have been seen, where I set seen = 1;

public ArrayList<Movie> getSeenMovies(){
    ArrayList<Movie> seenList = new ArrayList<Movie>();
    String selectQuery = "SELECT * FROM " + MOVIE_TABLE + " WHERE " + KEY_SEEN + " == " +1;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    if (cursor != null && cursor.moveToFirst()) {
        do {
            Movie m = new Movie();
            m.setMovieTitle(cursor.getString(1));
            m.setSeen(true);

            m.setAddWatchlist(Integer.parseInt(cursor.getString(3)) == 1);

            seenList.add(m);
        }
        while (cursor.moveToNext());
    }
    return seenList;
}

The NullPointerException comes when I try to populate my listview with the query results because of the movieList.size() in the getCount method of my MovieArrayAdapter class which says my movieList is null

MovieArrayAdapter

public class MovieArrayAdapter extends BaseAdapter {

private Context context;
private ArrayList<Movie> movieList;

//adapter constructor
public MovieArrayAdapter(Context context, ArrayList<Movie> movieList) {
    this.context = context;
    this.movieList = movieList;
}

//abstract method returns size of movie list
public int getCount() {
        return this.movieList.size();
}

//abstract method returns item at input position in list
public Object getItem(int pos){return this.movieList.get(pos);}

// abstract method gets item id at position i
public long getItemId(int pos){return pos;}

public View getView(int position, View convertView, ViewGroup parent){

    View v = View.inflate(context, R.layout.movie_list_entry, null);

    //finds MovieTitle textview field in the movie_list entry layout file
    TextView title = (TextView)v.findViewById(R.id.MovieTitle);

    //sets MovieTitle field to title of movie from list
    title.setText(movieList.get(position).getmMovieTitle());

    return v;}
}

The error:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.indiana.kupshah.movdex, PID: 4754
              java.lang.RuntimeException: Unable to start activity ComponentInfo{com.indiana.kupshah.movdex/com.indiana.kupshah.movdex.SeenList}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                  at android.app.ActivityThread.-wrap12(ActivityThread.java)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
               Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
                  at com.indiana.kupshah.movdex.MovieArrayAdapter.getCount(MovieArrayAdapter.java:32)
                  at android.widget.ListView.setAdapter(ListView.java:493)
                  at com.indiana.kupshah.movdex.SeenList.onCreate(SeenList.java:27)
                  at android.app.Activity.performCreate(Activity.java:6662)
                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
                  at android.app.ActivityThread.-wrap12(ActivityThread.java)
                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
                  at android.os.Handler.dispatchMessage(Handler.java:102)
                  at android.os.Looper.loop(Looper.java:154)
                  at android.app.ActivityThread.main(ActivityThread.java:6077)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

DBHandler movdexDB = new DBHandler(this); is an instance variable for the add movie form

This adds movie to the db when add button is clicked

public void onAddButtonClick(View v){
    EditText movieTitle = (EditText) findViewById(R.id.TitleText);
    CheckBox seen = (CheckBox) findViewById(R.id.SeenCheck);
    CheckBox watch = (CheckBox) findViewById(R.id.WatchCheck);

    //converts View values to types suitable for Movie class
    String addTitle = movieTitle.getText().toString();
    Boolean addSeen = seen.isChecked();
    Boolean addWatch = watch.isChecked();

    Movie movie = new Movie (addTitle,addSeen,addWatch);

    movdexDB.addMovie(movie);
}

This is the button click that starts the SeenList Activity

public void onSeenButtonClick(View v){
    Intent myIntent = new Intent(AddMovieEntry.this,SeenList.class);
    myIntent.putExtra("seen_list", movdexDB.getSeenMovies());
    startActivity(myIntent);
}

And lastly, the SeenList onCreate method

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_seen_list);

    //finds list view and populates from movies from the seen list,
    //using the layout established in the MovieAdapter arrayadapter class
    ListView SeenListView = (ListView) findViewById(R.id.SeenList);

    Intent i = getIntent();
    ArrayList<Movie> seenList;
    //sets the list of seen and watched movies
    seenList = (ArrayList<Movie>) i.getSerializableExtra("seenlist_movies");
    MovieArrayAdapter myAdapter = new MovieArrayAdapter(this, seenList);
    SeenListView.setAdapter(myAdapter);
}

Body:
Looks like you just need to protect access for null values in MovieArrayAdapter:

public int getCount(){
  return movieList != null ? movieList.size() : 0;
}


来源: stackexchange

问:
LinkedList implementation in Typescript
I am currently learning data structures and I am facing several problems when trying to implement LinkedList in TS. I added several methods but though it seems to work, the output is really weird.

My questions are in comments.

My code:

```<code>function LinkedList () {     //why doesn't fat arrow syntax work??
                             //ie. let LinkedList = () => {...this.append = () => {}...}
                            // prints out TypeError: t.append is not a function

let Node = (elem) => {
    this.elem = elem;
    this.next = null;
}

this.head = null;
this.len = 0;

this.append = (elem) => {

    let node = new Node(elem);
    let current;

    if(this.head === null){
        this.head = node;
    } else {
        current = this.head;
        while(current.next){
            current = current.next;
        }
        current.next = node;
    }
    this.len++;
}

this.removeAt = (pos) => {
    if(pos > -1 && pos < this.len){
        let current = this.head;
        let previous;
        let index = 0;

        if(pos === 0){
            this.head = current.next;
        } else {
            while(index++ < pos){
                previous = current;
                current = current.next;
            }
            previous.next = current.next;
        }
        this.len--;
        return current.elem;
    } else {
        return null;
    }
}

this.insert = (elem, pos) => {
    if(pos > -1 && pos < this.len){
        let current = this.head;
        let index = 0;
        let previous;
        let node = new Node(elem);

        if(pos === 0){
            node.next = current;
            this.head = node;
        } else {
            while(index++ < pos){
                previous = current;
                current = current.next;
            }
            node.next = current;
            previous.next = node;
        }
        this.len++;
        return true;
    } else {
        return false;
    }
}

this.toString = () => {
    var current = this.head;
    var str = '';
    while(current){
        str += current.elem; //output is undefinedundefinedundefined
               // str += JSON.stringify(current);
               // prints out {"next":{"next":{}}}{"next":{}}{}
        current = current.next;
    }
    return str;
}

}

let t = new LinkedList();
t.append('asd');   //Doesn't work with fat arrow function declaration
t.append(1);
t.append(0);
console.log(t);
let tt = t.removeAt(1);
console.log(t,'tt', tt);
t.insert('asd',2);
let ttt = t.insert('a', 1)
console.log(ttt);
console.log(t);
console.log(t.toString());
</code>```

答:
```<code>class Link {
  value: number;
  nextNode: Link;

  constructor(nodeValue: number, nodeReference: Link) {
    this.value = nodeValue;
    this.nextNode = nodeReference;
  }
}

class LinkedList {
  list: Link;
  _length: number = 0;

  insertLink(nodeIndex: number): boolean {
    if (this.list == null) {
      this.list = new Link(nodeIndex, null);
      this._length++;
      return true;
    } else {
      let temp = this.list;
      while (temp.nextNode != null) {
        temp = temp.nextNode;
      }
      temp.nextNode = new Link(nodeIndex, null);
      this._length++;
      return false;
    }
  }

  printLinkList(): void {
    let temp = this.list;
    if (this.list == null) {
      console.log('empty linked list');
    } else {
      while (temp.nextNode != null) {
        console.log(temp.value);
        temp = temp.nextNode;
      }
      console.log(temp.value);
    }
  }

  searchNodeByValue(i: number): number {
    let temp = this.list;
    let counter = 1;
    let position = null;
    if (temp == null) {
      console.log('empty list');
    } else {
      while (temp.nextNode != null) {
        if (temp.value === i) {
          position = counter;
        }
        counter++;
        temp = temp.nextNode;
      }
      //check if the  last element of the node
      if (temp.value === i) {
        position = counter;
      }
    }
    //console.log(position);
    if (position == null) {
      return 0;
    } else {
      return position;
    }
  }

  removeListItemByValue(i: number): boolean {
    if (this.list == null) {
      return true;
    } else {
      let itemPosition = this.searchNodeByValue(i);
      if (itemPosition == 0) {
        return true;
      } else {
        let temp = this.list;

        //if its the first element in the stack
        if (itemPosition == 1) {
          this.list = this.list.nextNode;
          return true;
        }

        //if the element is not first or last
        while (temp.nextNode.value != i) {
          console.log('in here');
          temp = temp.nextNode;
        }
        temp.nextNode = temp.nextNode.nextNode;
      }
      return true;
    }
  }

  removeListItemByPos(idx: number): boolean {
    let temp = this.list;
    let counter: number = 1;

    if (idx > this._length) return false;

    if (idx == 1) {
      this.list = this.list.nextNode;
      return true;
    }

    while (counter != idx - 1) {
      temp = temp.nextNode;
      counter++;
    }
    temp.nextNode = temp.nextNode.nextNode;
  }

}

const linkedList = new LinkedList();
linkedList.insertLink(1);
linkedList.insertLink(2);
linkedList.insertLink(3);
linkedList.insertLink(4);

linkedList.removeListItemByPos(4);
linkedList.insertLink(5);

linkedList.printLinkList();
</code>```

ContentLicense: CC BY-SA 3.0

Title: LinkedList implementation in Typescript

Body:
I am currently learning data structures and I am facing several problems when trying to implement LinkedList in TS. I added several methods but though it seems to work, the output is really weird.

My questions are in comments.

My code:

function LinkedList () {     //why doesn't fat arrow syntax work??
                             //ie. let LinkedList = () => {...this.append = () => {}...}
                            // prints out TypeError: t.append is not a function

let Node = (elem) => {
    this.elem = elem;
    this.next = null;
}

this.head = null;
this.len = 0;

this.append = (elem) => {

    let node = new Node(elem);
    let current;

    if(this.head === null){
        this.head = node;
    } else {
        current = this.head;
        while(current.next){
            current = current.next;
        }
        current.next = node;
    }
    this.len++;
}

this.removeAt = (pos) => {
    if(pos > -1 && pos < this.len){
        let current = this.head;
        let previous;
        let index = 0;

        if(pos === 0){
            this.head = current.next;
        } else {
            while(index++ < pos){
                previous = current;
                current = current.next;
            }
            previous.next = current.next;
        }
        this.len--;
        return current.elem;
    } else {
        return null;
    }
}

this.insert = (elem, pos) => {
    if(pos > -1 && pos < this.len){
        let current = this.head;
        let index = 0;
        let previous;
        let node = new Node(elem);

        if(pos === 0){
            node.next = current;
            this.head = node;
        } else {
            while(index++ < pos){
                previous = current;
                current = current.next;
            }
            node.next = current;
            previous.next = node;
        }
        this.len++;
        return true;
    } else {
        return false;
    }
}

this.toString = () => {
    var current = this.head;
    var str = '';
    while(current){
        str += current.elem; //output is undefinedundefinedundefined
               // str += JSON.stringify(current);
               // prints out {"next":{"next":{}}}{"next":{}}{}
        current = current.next;
    }
    return str;
}

}

let t = new LinkedList();
t.append('asd');   //Doesn't work with fat arrow function declaration
t.append(1);
t.append(0);
console.log(t);
let tt = t.removeAt(1);
console.log(t,'tt', tt);
t.insert('asd',2);
let ttt = t.insert('a', 1)
console.log(ttt);
console.log(t);
console.log(t.toString());

ContentLicense: CC BY-SA 4.0


问:
Joining sql views in oracle sql
How can I join views using sql? I'm using Oracle at the moment?

Sql view 1

```<code>CREATE VIEW florence_staff AS
SELECT *
FROM staff
WHERE libname ='florence'
</code>```

Sql view 2

```<code>CREATE VIEW alexandria_staff AS
SELECT *
FROM staff
WHERE libname ='alexandria'
</code>```

I'm doing this to check if the fragmentation is correct, if you get what i mean. Thanks :))

答:
These will be distinct result sets as the libname is different so use UNION ALL rather than UNION

```<code>SELECT * FROM florence_staff
UNION ALL
SELECT * FROM alexandria_staff
</code>```

ContentLicense: CC BY-SA 2.5

Title: Joining sql views in oracle sql

Body:
How can I join views using sql? I'm using Oracle at the moment?

Sql view 1

CREATE VIEW florence_staff AS
SELECT *
FROM staff
WHERE libname ='florence'

Sql view 2

CREATE VIEW alexandria_staff AS
SELECT *
FROM staff
WHERE libname ='alexandria'

I'm doing this to check if the fragmentation is correct, if you get what i mean. Thanks :))

Body:
These will be distinct result sets as the libname is different so use UNION ALL rather than UNION

SELECT * FROM florence_staff
UNION ALL
SELECT * FROM alexandria_staff


问:
How to Show the Code and design window in dreamwaver
I cant see the design of my code in dreamwaver. i want to switch the code to design. please help meenter image description here</p>

答:
Got to - View, Toolbar (right at the bottom), and select Document from the
fly out list (assuming it is unticked). </p>


问:
PL SQL relationship and procedure issues
I would like to ask some help with pl/sql oracle. I am trying to figure out this object oriented database stuff but not much success so far. I am into programming and i understand rdbms as well, already managed some complex database but this object oriented is over my understanding.
So the task is the following:
There are teachers and students. need to make a timetable which has two type of lessons. day and afternoon.
day class can have maximum 10 students and afternoon max 5.

the followings i have so far:

```<code>/*create student type and table*/
create type student_typ as object(
st_id char(3),
st_name varchar(50)
)
create table student_tbl of student_typ(
st_id primary key not null,
st_name not null
)

/*create teacher type and table*/
create type teacher_typ as object(
tr_id char(3),
tr_name varchar(50)
)
create table teacher_tbl of teacher_typ(
tr_id primary key not null,
tr_name not null
)

/*create array type to store the student id-s*/
create type students_arr as varray(20) of char(3);

/*create table for timetable*/
create table timetable_tbl(
t_ID char(5),
t_Date date,
t_Time varchar(5), /*store time format as 12:00*/
t_Type char(1),
teacher ref teacher_typ scope is teacher_tbl,
students students_arr,
constraint chk_type check(t_Type='D' or t_Type='N')
)

/*insert values into the tables*/
insert into teacher_tbl values ('t01','bob');
insert into teacher_tbl values ('t02','smith');
insert into student_tbl values ('s01','lara');
insert into student_tbl values ('s02','john');

/*insert values into timetable*/
insert into timetable_tbl( select 't01','01-Apr-17','09:00','D',ref(t),students_arr('s01','s02') from teacher_tbl t where t.tr_ID='t01');
insert into timetable_tbl( select 't02','01-Apr-17','19:00','N',ref(t),students_arr('s01') from teacher_tbl t where t.tr_ID='t02');

/*display timetable records*/
select t_ID, t_Date, t_Time, t_Type, deref(teacher).tr_ID,deref(teacher).tr_Name, students from timetable_tbl;

/*create procedure to add new student*/
create or replace procedure Add_Student(
v_id in student_tbl.st_id%type,
v_name in student_tbl.st_name%type,
verror out varchar2 )
is begin
insert into student_tbl (st_id,st_name) values (v_id,v_name);
commit;
exception when others then
verror := sqlerrm;
end;

/*call add_student procedure*/
declare
verror varchar2(500);
begin
Add_Student('s03','sam',verror);
end;
</code>```

So that is what i have so far. The questions are the next.

Is this the right way to do this?

how can i reference the students in the varray? i have tried ref as with the teacher ref but no result at all?
students student_arr ref student_typ scope is student_tbl; this code is not working.
the students_arr array should accept only existing records from student table

how can i create a procedure for timetable? because the main thing there is when the t_Type is "D" then the student_arr should allow maximum 10 values
and if the t_Type is "N" then the student_arr should allow maximum 5 values only. i Should do something like add_record procedure for timetable and using if statement but i am not sure it would be a good idea.
if t_type='D' then
if students.count<=10
or
if t_type='N' then
if students.count<=5

Im kind of stucked now. I have watched a lot of tutorials about pl sql but got even more confused. The annoying things is that i managed the same with
rdbms (sql server) and java in no time. But this language and object database got me hard now.

Any help would be appropriated!

答:
It seemed i was not clear about the questions. So here is the things again but in a simplified way.

There is a person class which holds info about persons. And there is a test class which holds other info like a timetable but it holds persons in a column. So it is a multi-valued column which i can manage with either using varray or nested table type.

The problem is how to use ref in this way. I can use ref for a single object but not in collection.

```<code>/*create person type and table*/
create type person_ty as object(
pid varchar(3),
pName varchar(50)
);
create table person_tbl of person_ty;

/*create table which will be used as nested table*/
create type nest_ty as object(
tID varchar(3),
person ref person_ty
);
create type nest_tbl as table of nest_ty;

/*create table for test*/
create table test_tbl(
tID varchar(3),
tDate date,
persons nest_tbl
)nested table persons store as persons;
</code>```

so how can i insert data into the test table?

i know a single nested table without ref type would be:

```<code>insert into test_tbl values ('123','12-dec-17', nest_tbl(
nest_ty('123','p01'),
nest_ty('345','p06')
));
</code>```

and i know that insert data with a single ref type looks like this:

```<code>insert into test_tbl
select '123', '12-dec-17', ref(a) from person_tbl a where a.pID='p01';
</code>```

Again i am very new with oodb and plsql so my questions might not be clear or make no sense. In that case im sorry.
Still appropriate all kind of help.

Body:
I would like to ask some help with pl/sql oracle. I am trying to figure out this object oriented database stuff but not much success so far. I am into programming and i understand rdbms as well, already managed some complex database but this object oriented is over my understanding.
So the task is the following:
There are teachers and students. need to make a timetable which has two type of lessons. day and afternoon.
day class can have maximum 10 students and afternoon max 5.

the followings i have so far:

/*create student type and table*/
create type student_typ as object(
st_id char(3),
st_name varchar(50)
)
create table student_tbl of student_typ(
st_id primary key not null,
st_name not null
)

/*create teacher type and table*/
create type teacher_typ as object(
tr_id char(3),
tr_name varchar(50)
)
create table teacher_tbl of teacher_typ(
tr_id primary key not null,
tr_name not null
)

/*create array type to store the student id-s*/
create type students_arr as varray(20) of char(3);

/*create table for timetable*/
create table timetable_tbl(
t_ID char(5),
t_Date date,
t_Time varchar(5), /*store time format as 12:00*/
t_Type char(1),
teacher ref teacher_typ scope is teacher_tbl,
students students_arr,
constraint chk_type check(t_Type='D' or t_Type='N')
)

/*insert values into the tables*/
insert into teacher_tbl values ('t01','bob');
insert into teacher_tbl values ('t02','smith');
insert into student_tbl values ('s01','lara');
insert into student_tbl values ('s02','john');

/*insert values into timetable*/
insert into timetable_tbl( select 't01','01-Apr-17','09:00','D',ref(t),students_arr('s01','s02') from teacher_tbl t where t.tr_ID='t01');
insert into timetable_tbl( select 't02','01-Apr-17','19:00','N',ref(t),students_arr('s01') from teacher_tbl t where t.tr_ID='t02');

/*display timetable records*/
select t_ID, t_Date, t_Time, t_Type, deref(teacher).tr_ID,deref(teacher).tr_Name, students from timetable_tbl;

/*create procedure to add new student*/
create or replace procedure Add_Student(
v_id in student_tbl.st_id%type,
v_name in student_tbl.st_name%type,
verror out varchar2 )
is begin
insert into student_tbl (st_id,st_name) values (v_id,v_name);
commit;
exception when others then
verror := sqlerrm;
end;

/*call add_student procedure*/
declare
verror varchar2(500);
begin
Add_Student('s03','sam',verror);
end;

So that is what i have so far. The questions are the next.

Is this the right way to do this?

how can i reference the students in the varray? i have tried ref as with the teacher ref but no result at all?
students student_arr ref student_typ scope is student_tbl; this code is not working.
the students_arr array should accept only existing records from student table

how can i create a procedure for timetable? because the main thing there is when the t_Type is "D" then the student_arr should allow maximum 10 values
and if the t_Type is "N" then the student_arr should allow maximum 5 values only. i Should do something like add_record procedure for timetable and using if statement but i am not sure it would be a good idea.
if t_type='D' then
if students.count<=10
or
if t_type='N' then
if students.count<=5

Im kind of stucked now. I have watched a lot of tutorials about pl sql but got even more confused. The annoying things is that i managed the same with
rdbms (sql server) and java in no time. But this language and object database got me hard now.

Any help would be appropriated!

Body:
It seemed i was not clear about the questions. So here is the things again but in a simplified way.

There is a person class which holds info about persons. And there is a test class which holds other info like a timetable but it holds persons in a column. So it is a multi-valued column which i can manage with either using varray or nested table type.

The problem is how to use ref in this way. I can use ref for a single object but not in collection.

/*create person type and table*/
create type person_ty as object(
pid varchar(3),
pName varchar(50)
);
create table person_tbl of person_ty;

/*create table which will be used as nested table*/
create type nest_ty as object(
tID varchar(3),
person ref person_ty
);
create type nest_tbl as table of nest_ty;

/*create table for test*/
create table test_tbl(
tID varchar(3),
tDate date,
persons nest_tbl
)nested table persons store as persons;

so how can i insert data into the test table?

i know a single nested table without ref type would be:

insert into test_tbl values ('123','12-dec-17', nest_tbl(
nest_ty('123','p01'),
nest_ty('345','p06')
));

and i know that insert data with a single ref type looks like this:

insert into test_tbl
select '123', '12-dec-17', ref(a) from person_tbl a where a.pID='p01';

Again i am very new with oodb and plsql so my questions might not be clear or make no sense. In that case im sorry.
Still appropriate all kind of help.


问:
What type of POWER8 PMU events should be maximized?
I perform a performance analysis of an application running on IBM POWER8 server following the CPI breakdown model for POWER8.

I understand that I need to reduce the percentage of stalls caused, for example, by cache misses (PM_CMPLU_STALL_DCACHE_MISS) or branch mispredictions (PM_CMPLU_STALL_BRU). The POWER7 performance analysis tutorial tells that a well-written application has a high final instruction completion percentage (PM_1PLUS_PPC_CMPL).

Do I understand correctly that for POWER8 I need to maximize the percentage for the PM_GRP_CMPL metric? What other PMU-based metrics should I try to maximize?

答:
Pointing out the obvious: you need to optimize your source code
to minimize PM_RUN_CYC, the number of cycles it takes for your software task to complete.

The reference you gave breaks down PM_RUN_CYC as PM_CMPLU_STALL + PM_GCT_NOSLOT_CYC + PM_GRP_CMPL.

You'd want to reduce the largest contributor of the three components. Minimize stalls for example by reorganizing your code to reduce cache misses. The "No slot" cycles have to do with branch misprediction and the instruction cache misses.

PM_GRP_CMPL is "Microcoded instructions
that span multiple groups will generate this event once per group". Not clear what this tells. In any case, you want to minimize -- not maximize these counts.


问:
Changing only one value of a key in a dictionary that has multiple values
I have a key with multiple values assigned. I would like to ask the user for input (new_population), and replace the old value (current_population) within the key. I would like the other value within the key (num) to remain unaffected.

```<code>current_population = 5
num = 3
dict = {}
dict["key"] = [current_population, num]

new_population = input("What is the new population?")
</code>```

Say (for example sake), the value of new_population is 10. My goal is a final output of:

```<code>{'key': [10, 3]}
</code>```

How would I go about doing this?

答:
```<code>dict["key"][0] = new_population
</code>```

Body:
I have a key with multiple values assigned. I would like to ask the user for input (new_population), and replace the old value (current_population) within the key. I would like the other value within the key (num) to remain unaffected.

current_population = 5
num = 3
dict = {}
dict["key"] = [current_population, num]

new_population = input("What is the new population?")

Say (for example sake), the value of new_population is 10. My goal is a final output of:

{'key': [10, 3]}

How would I go about doing this?

Body: dict["key"][0] = new_population


问:
nested loops to IDataReader
I have a program that writes a huge DataTable (2.000.000 to 70.000.000 rows, depends on the configuration) to a database using a SqlBulkCopy.

I decided to change the loop that populates this table into a IDataReader, because the amount of rows often causes an OutOfMemoryException.

The table is populated like this

```<code>// int[] firsts;
// string[] seconds;
// byte[] thirds;
var table = new DataTable();
foreach(var f in firsts)
{
    foreach(var s in seconds)
    {
        foreach(var t in thirds)
        {
            var row = table.NewRow();
            row[0] = f;
            row[1] = s;
            row[2] = t;
            table.Rows.Add(row);
        }
    }
    // here I also bulk load the table and clear it
}
</code>```

so in my IDataReader class I will loop by index. This is my attempt.

```<code>class TableReader : IDataReader
{
    bool Eof = false;

    int FirstIndex;
    int SecondIndex;
    int ThirdIndex;

    //those are populated via constructor
    int[] firsts;
    string[] seconds;
    byte[] thirds;

    // this will be retrieved automatically via indexer
    object[] Values;

    public bool Read()
    {
        if(ThirdIndex != thirds.Length
            && SecondIndex < seconds.Length
            && FirstIndex < firsts.Length)
        {
            Values[0] = firsts[FirstIndex];
            Values[1] = seconds[SecondIndex];
            Values[2] = thirds[ThirdIndex++];
        }
        else if(SecondIndex != seconds.Length)
        {
            ThirdIndex  = 0;
            SecondIndex++;
        }
        else if(FirstIndex != firsts.Length)
        {
            SecondIndex = 0;
            FirstIndex++;
        }
        else
        {
            Eof = true;
        }
        return !Eof;
    }
}
</code>```

I've created this code using a while(true) loop with a break instead of the Eof, but I can't seem to figure out how to do this.

Anyone can help?

答:
This is actually possible if you implement IDataReader and use the "yield return" keyword to provide rows.  IDataReader is a bit of a pain to implement, but it isn't complex at all.  The code below can be adapted to load a terabyte worth of data to the database and never run out of memory.

I replaced the DataRow objects with a single object array that is reused throughout the data read.

Because there's no DataTable object to represent the columns, I had to do this myself by storing the data types and column names separately.

```<code>class TestDataReader : IDataReader {
    int[] firsts = { 1, 2, 3, 4 };
    string[] seconds = { "abc", "def", "ghi" };
    byte[] thirds = { 0x30, 0x31, 0x32 };

    // The data types of each column.
    Type[] dataTypes = { typeof(int), typeof(string), typeof(byte) };

    // The names of each column.
    string[] names = { "firsts", "seconds", "thirds" };

    // This function uses coroutines to turn the "push" approach into a "pull" approach.
    private IEnumerable<object[]> GetRows() {
        // Just re-use the same array.
        object[] row = new object[3];
        foreach (var f in firsts) {
            foreach (var s in seconds) {
                foreach (var t in thirds) {
                    row[0] = f;
                    row[1] = s;
                    row[2] = t;
                    yield return row;
                }
            }
            // here I also bulk load he table and clear it
        }
    }

    // Everything below basically wraps this.
    IEnumerator<object[]> rowProvider;

    public TestDataReader() {
        rowProvider = GetRows().GetEnumerator();
    }

    public object this[int i] {
        get {
            return GetValue(i);
        }
    }

    public object this[string name] {
        get {
            return GetValue(GetOrdinal(name));
        }
    }

    public int  Depth                       { get { return 0;                               } }
    public int  FieldCount                  { get { return dataTypes.Length;                } }
    public bool IsClosed                    { get { return false;                           } }
    public int  RecordsAffected             { get { return 0;                               } }

    // These don't really do anything.
    public void Close()                     { Dispose();                                    }
    public void Dispose()                   { rowProvider.Dispose();                        }

    public string   GetDataTypeName(int i)  { return dataTypes[i].Name;                     }
    public Type     GetFieldType(int i)     { return dataTypes[i];                          }

    // These functions get basic data types.
    public bool     GetBoolean(int i)       { return (bool)     rowProvider.Current[i];     }
    public byte     GetByte(int i)          { return (byte)     rowProvider.Current[i];     }
    public char     GetChar(int i)          { return (char)     rowProvider.Current[i];     }
    public DateTime GetDateTime(int i)      { return (DateTime) rowProvider.Current[i];     }
    public decimal  GetDecimal(int i)       { return (decimal)  rowProvider.Current[i];     }
    public double   GetDouble(int i)        { return (double)   rowProvider.Current[i];     }
    public float    GetFloat(int i)         { return (float)    rowProvider.Current[i];     }
    public Guid     GetGuid(int i)          { return (Guid)     rowProvider.Current[i];     }
    public short    GetInt16(int i)         { return (short)    rowProvider.Current[i];     }
    public int      GetInt32(int i)         { return (int)      rowProvider.Current[i];     }
    public long     GetInt64(int i)         { return (long)     rowProvider.Current[i];     }
    public string   GetString(int i)        { return (string)   rowProvider.Current[i];     }
    public object   GetValue(int i)         { return (object)   rowProvider.Current[i];     }
    public string   GetName(int i)          { return names[i];                              }

    public bool IsDBNull(int i) {
        object obj = rowProvider.Current[i];
        return obj == null || obj is DBNull;
    }

    // Looks up a field number given its name.
    public int GetOrdinal(string name) {
        return Array.FindIndex(names, x => x.Equals(name, StringComparison.OrdinalIgnoreCase));
    }

    // Populate "values" given the current row of data.
    public int GetValues(object[] values) {
        if (values == null) {
            return 0;
        } else {
            int len = Math.Min(values.Length, rowProvider.Current.Length);
            Array.Copy(rowProvider.Current, values, len);
            return len;
        }
    }

    // This reader only supports a single result set.
    public bool NextResult() {
        return false;
    }

    // Move to the next row.
    public bool Read() {
        return rowProvider.MoveNext();
    }

    // Don't bother implementing these in any meaningful way.
    public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) {
        throw new NotImplementedException();
    }

    public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) {
        throw new NotImplementedException();
    }

    public IDataReader GetData(int i) {
        throw new NotImplementedException();
    }

    public DataTable GetSchemaTable() {
        return null;
    }

}
</code>```

Title: nested loops to IDataReader

Body:
I have a program that writes a huge DataTable (2.000.000 to 70.000.000 rows, depends on the configuration) to a database using a SqlBulkCopy.

I decided to change the loop that populates this table into a IDataReader, because the amount of rows often causes an OutOfMemoryException.

The table is populated like this

// int[] firsts;
// string[] seconds;
// byte[] thirds;
var table = new DataTable();
foreach(var f in firsts)
{
    foreach(var s in seconds)
    {
        foreach(var t in thirds)
        {
            var row = table.NewRow();
            row[0] = f;
            row[1] = s;
            row[2] = t;
            table.Rows.Add(row);
        }
    }
    // here I also bulk load the table and clear it
}

so in my IDataReader class I will loop by index. This is my attempt.

class TableReader : IDataReader
{
    bool Eof = false;

    int FirstIndex;
    int SecondIndex;
    int ThirdIndex;

    //those are populated via constructor
    int[] firsts;
    string[] seconds;
    byte[] thirds;

    // this will be retrieved automatically via indexer
    object[] Values;

    public bool Read()
    {
        if(ThirdIndex != thirds.Length
            && SecondIndex < seconds.Length
            && FirstIndex < firsts.Length)
        {
            Values[0] = firsts[FirstIndex];
            Values[1] = seconds[SecondIndex];
            Values[2] = thirds[ThirdIndex++];
        }
        else if(SecondIndex != seconds.Length)
        {
            ThirdIndex  = 0;
            SecondIndex++;
        }
        else if(FirstIndex != firsts.Length)
        {
            SecondIndex = 0;
            FirstIndex++;
        }
        else
        {
            Eof = true;
        }
        return !Eof;
    }
}

I've created this code using a while(true) loop with a break instead of the Eof, but I can't seem to figure out how to do this.

Anyone can help?

Body:
This is actually possible if you implement IDataReader and use the "yield return" keyword to provide rows.  IDataReader is a bit of a pain to implement, but it isn't complex at all.  The code below can be adapted to load a terabyte worth of data to the database and never run out of memory.

I replaced the DataRow objects with a single object array that is reused throughout the data read.

Because there's no DataTable object to represent the columns, I had to do this myself by storing the data types and column names separately.

class TestDataReader : IDataReader {
    int[] firsts = { 1, 2, 3, 4 };
    string[] seconds = { "abc", "def", "ghi" };
    byte[] thirds = { 0x30, 0x31, 0x32 };

    // The data types of each column.
    Type[] dataTypes = { typeof(int), typeof(string), typeof(byte) };

    // The names of each column.
    string[] names = { "firsts", "seconds", "thirds" };

    // This function uses coroutines to turn the "push" approach into a "pull" approach.
    private IEnumerable<object[]> GetRows() {
        // Just re-use the same array.
        object[] row = new object[3];
        foreach (var f in firsts) {
            foreach (var s in seconds) {
                foreach (var t in thirds) {
                    row[0] = f;
                    row[1] = s;
                    row[2] = t;
                    yield return row;
                }
            }
            // here I also bulk load he table and clear it
        }
    }

    // Everything below basically wraps this.
    IEnumerator<object[]> rowProvider;

    public TestDataReader() {
        rowProvider = GetRows().GetEnumerator();
    }

    public object this[int i] {
        get {
            return GetValue(i);
        }
    }

    public object this[string name] {
        get {
            return GetValue(GetOrdinal(name));
        }
    }

    public int  Depth                       { get { return 0;                               } }
    public int  FieldCount                  { get { return dataTypes.Length;                } }
    public bool IsClosed                    { get { return false;                           } }
    public int  RecordsAffected             { get { return 0;                               } }

    // These don't really do anything.
    public void Close()                     { Dispose();                                    }
    public void Dispose()                   { rowProvider.Dispose();                        }

    public string   GetDataTypeName(int i)  { return dataTypes[i].Name;                     }
    public Type     GetFieldType(int i)     { return dataTypes[i];                          }

    // These functions get basic data types.
    public bool     GetBoolean(int i)       { return (bool)     rowProvider.Current[i];     }
    public byte     GetByte(int i)          { return (byte)     rowProvider.Current[i];     }
    public char     GetChar(int i)          { return (char)     rowProvider.Current[i];     }
    public DateTime GetDateTime(int i)      { return (DateTime) rowProvider.Current[i];     }
    public decimal  GetDecimal(int i)       { return (decimal)  rowProvider.Current[i];     }
    public double   GetDouble(int i)        { return (double)   rowProvider.Current[i];     }
    public float    GetFloat(int i)         { return (float)    rowProvider.Current[i];     }
    public Guid     GetGuid(int i)          { return (Guid)     rowProvider.Current[i];     }
    public short    GetInt16(int i)         { return (short)    rowProvider.Current[i];     }
    public int      GetInt32(int i)         { return (int)      rowProvider.Current[i];     }
    public long     GetInt64(int i)         { return (long)     rowProvider.Current[i];     }
    public string   GetString(int i)        { return (string)   rowProvider.Current[i];     }
    public object   GetValue(int i)         { return (object)   rowProvider.Current[i];     }
    public string   GetName(int i)          { return names[i];                              }

    public bool IsDBNull(int i) {
        object obj = rowProvider.Current[i];
        return obj == null || obj is DBNull;
    }

    // Looks up a field number given its name.
    public int GetOrdinal(string name) {
        return Array.FindIndex(names, x => x.Equals(name, StringComparison.OrdinalIgnoreCase));
    }

    // Populate "values" given the current row of data.
    public int GetValues(object[] values) {
        if (values == null) {
            return 0;
        } else {
            int len = Math.Min(values.Length, rowProvider.Current.Length);
            Array.Copy(rowProvider.Current, values, len);
            return len;
        }
    }

    // This reader only supports a single result set.
    public bool NextResult() {
        return false;
    }

    // Move to the next row.
    public bool Read() {
        return rowProvider.MoveNext();
    }

    // Don't bother implementing these in any meaningful way.
    public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) {
        throw new NotImplementedException();
    }

    public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) {
        throw new NotImplementedException();
    }

    public IDataReader GetData(int i) {
        throw new NotImplementedException();
    }

    public DataTable GetSchemaTable() {
        return null;
    }

}


问:
if an a link contain something in the href change the href to this
i want to check if the href contains 'coming-soon' if it does change the href to go to my products page:

```<code>$('a[href$="coming-soon"]').attr('href', '/products.aspx');
</code>```

cant work this out.

答:
$= is "attribute-ends-with", use *= for "attribute contains", like this:

```<code>$('a[href*="coming-soon"]').attr('href', '/products.aspx');
</code>```

Body:
i want to check if the href contains 'coming-soon' if it does change the href to go to my products page:

$('a[href$="coming-soon"]').attr('href', '/products.aspx');

cant work this out.

Body:
$= is "attribute-ends-with", use *= for "attribute contains", like this:

$('a[href*="coming-soon"]').attr('href', '/products.aspx');


问:
How do I strip a file extension from a string in C?
How do I strip a file extension from a string in C?

For example,

If I have the filenames with the file extensions

hello.txt

hello.c

hello.java

should all result in just the filename without the extension as

hello

the length of the file extension shouldn't matter.

the function should also be portable and not system dependent.

I know how to get the file extension using strchr or strrchr. I've done this in Bash and in Python, but I've never had to do this in C.

Note: This is for a personal exercise to help strengthen my understanding of the C programming language.

答:
I don't know that there is a best way, but here is one way. Presumably you don't want to strip the name from dot files. Also, you probably only want to remove the characters from the last dot to the end of the string. Note that in the code below, the input string is modified, so the filename can't be a string literal, but must be a null-terminated character array.

```<code>#include <stdio.h>
#include <string.h>

void strip_ext(char *);

int main(void)
{
    char filename1[] = "myfile.txt";
    char filename2[] = ".emacs";
    char filename3[] = "anotherfile.";
    char filename4[] = "nodot";
    char filename5[] = "";
    char filename6[] = "dot.dot.dot";

    strip_ext(filename1);
    strip_ext(filename2);
    strip_ext(filename3);
    strip_ext(filename4);
    strip_ext(filename5);
    strip_ext(filename6);

    printf("file1: %s\n", filename1);
    printf("file2: %s\n", filename2);
    printf("file3: %s\n", filename3);
    printf("file4: %s\n", filename4);
    printf("file5: %s\n", filename5);
    printf("file6: %s\n", filename6);

    return 0;
}

void strip_ext(char *fname)
{
    char *end = fname + strlen(fname);

    while (end > fname && *end != '.') {
        --end;
    }

    if (end > fname) {
        *end = '\0';
    }
}
</code>```

Program output:

file1: myfile
file2: .emacs
file3: anotherfile
file4: nodot
file5:
file6: dot.dot
```

<h2>Update</h2>

<p>@David C. Rankin has pointed out that more complex filepaths may complicate matters. Below is a modification to the <code>strip_ext()</code> function that stops looking for a dot when either a forward or back slash is encountered, in which case the filename string remains unchanged:</p>

```void strip_ext(char *fname)
{
    char *end = fname + strlen(fname);

    while (end > fname && *end != '.' && *end != '\\' && *end != '/') {
        --end;
    }
    if ((end > fname && *end == '.') &&
        (*(end - 1) != '\\' && *(end - 1) != '/')) {
        *end = '\0';
    }
}
```

<p>Running this function with the same test strings, and the additional test strings:</p>

```char filename7[] = "/my.dir/myfile";
char filename8[] = "/dir/.filename";
```

<p>generates this output:</p>

<pre class="lang-none prettyprint-override"><code>file1: myfile
file2: .emacs
file3: anotherfile
file4: nodot
file5:
file6: dot.dot
file7: /my.dir/myfile
file8: /dir/.filename
</code>```

Body:
I don't know that there is a best way, but here is one way. Presumably you don't want to strip the name from dot files. Also, you probably only want to remove the characters from the last dot to the end of the string. Note that in the code below, the input string is modified, so the filename can't be a string literal, but must be a null-terminated character array.

#include <stdio.h>
#include <string.h>

void strip_ext(char *);

int main(void)
{
    char filename1[] = "myfile.txt";
    char filename2[] = ".emacs";
    char filename3[] = "anotherfile.";
    char filename4[] = "nodot";
    char filename5[] = "";
    char filename6[] = "dot.dot.dot";

    strip_ext(filename1);
    strip_ext(filename2);
    strip_ext(filename3);
    strip_ext(filename4);
    strip_ext(filename5);
    strip_ext(filename6);

    printf("file1: %s\n", filename1);
    printf("file2: %s\n", filename2);
    printf("file3: %s\n", filename3);
    printf("file4: %s\n", filename4);
    printf("file5: %s\n", filename5);
    printf("file6: %s\n", filename6);

    return 0;
}

void strip_ext(char *fname)
{
    char *end = fname + strlen(fname);

    while (end > fname && *end != '.') {
        --end;
    }

    if (end > fname) {
        *end = '\0';
    }
}

Program output:

file1: myfile
file2: .emacs
file3: anotherfile
file4: nodot
file5:
file6: dot.dot

Update

@David C. Rankin has pointed out that more complex filepaths may complicate matters. Below is a modification to the strip_ext() function that stops looking for a dot when either a forward or back slash is encountered, in which case the filename string remains unchanged:

void strip_ext(char *fname)
{
    char *end = fname + strlen(fname);

    while (end > fname && *end != '.' && *end != '\\' && *end != '/') {
        --end;
    }
    if ((end > fname && *end == '.') &&
        (*(end - 1) != '\\' && *(end - 1) != '/')) {
        *end = '\0';
    }
}

Running this function with the same test strings, and the additional test strings:

char filename7[] = "/my.dir/myfile";
char filename8[] = "/dir/.filename";

generates this output:

file1: myfile
file2: .emacs
file3: anotherfile
file4: nodot
file5:
file6: dot.dot
file7: /my.dir/myfile
file8: /dir/.filename


问:
UIView Subclass Set Own Height + Constraints In UIViewController + Storyboard in Swift
I have a UIViewController subclass that contains a UITableView, a subclass of UIView called ICYCollapsableInputView, and another UIView subclass called ICYHeaderVIew.

ICYHeaderView is the rounded off looking UIView shown in the screenshots.  It contains a round button - the one with the green "add" (+) button.

ICYCollapsableInputView is a view that will for now have a UITextField and a Save button.  I want to be able to expand and collapse this view from the UIViewController by calling the appropriate functions of the ICYCollapsableInputView.

When the user taps the round button on the ICYHeaderView, Ithe ICYCollapsableInputView is supposed to expand in height, pushing down the UITableView. I have the ICYCollapsableInputView expanding and collapsing, but I can't figure out how to get the UITableView to respond to the changes.  (See Animation)

I colored the main view in the xib with a RED background and the view I added in it with a BLUE background (see screenshot)

I can resize the ICYCollapsableInputView (as seen in the code and animation) using its own height constraint, but the UITableView constraint seems to ignore it.

Here is the code from ICYCollapsableInputView:

```<code>class ICYCollapsableInputView: UIView {

var view: UIView!

@IBOutlet weak var heightConstraint: NSLayoutConstraint!

@IBInspectable public var collapsedHeight: CGFloat = 150 {
    didSet {
        self.heightConstraint.constant = collapsedHeight
    }
}
@IBInspectable public var expandedHeight: CGFloat = 250 {
    didSet {
        self.heightConstraint.constant = expandedHeight
    }
}

// MARK: - Init

func loadFromNib() -> UIView {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: "ICYCollapsableInputView", bundle: bundle)
    let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView

    return view
}

override init(frame: CGRect) {
    // 1. setup any properties here

    // 2. call super.init(frame:)
    super.init(frame: frame)
    // 3. Setup view from .xib file
    xibSetup()

}

required init?(coder aDecoder: NSCoder) {
    // 1. setup any properties here

    // 2. call super.init(coder:)
    super.init(coder: aDecoder)
    // 3. Setup view from .xib file
    xibSetup()
}

func xibSetup() {
    view = loadFromNib()
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(view)
    self.heightConstraint.constant = self.collapsedHeight
    var rect = self.frame
    rect.size.height = self.collapsedHeight
    self.frame = rect
    self.view.frame = rect

}

func revealInputView() {
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
        var rect = self.frame
        rect.size.height = self.expandedHeight
        self.frame = rect
        self.heightConstraint.constant = self.expandedHeight
        self.view.layoutIfNeeded()
    }, completion: nil)
}

func closeInputView() {
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
        self.heightConstraint.constant = self.collapsedHeight
        var rect = self.frame
        rect.size.height = self.collapsedHeight
        self.frame = rect
        self.view.layoutIfNeeded()
    }, completion: nil)

}

 }
</code>```

答:
All you need ia just changing the height constraints.

```<code>    func revealInputView() {
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {

            self.heightConstraint.constant = self.expandedHeight //or 250
            self.view.layoutIfNeeded()
        }, completion: nil)
    }

    func closeInputView() {
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {

            self.heightConstraint.constant = self.collapsedHeight //or 150
self.view.layoutIfNeeded()
        }, completion: nil)
}
</code>```

And Constraints in Storyboard should be following

for inputVW

Trailaing space to superview - 0 , leading space to superview - 0, top space to superview - 0 , bottom space to tableview - 0

for TableView

top space to inputVw - 0, leading space to superview - 0, trailing space to super view - 0, bottom space to superview - 0

Body:
I have a UIViewController subclass that contains a UITableView, a subclass of UIView called ICYCollapsableInputView, and another UIView subclass called ICYHeaderVIew.

ICYHeaderView is the rounded off looking UIView shown in the screenshots.  It contains a round button - the one with the green "add" (+) button.

ICYCollapsableInputView is a view that will for now have a UITextField and a Save button.  I want to be able to expand and collapse this view from the UIViewController by calling the appropriate functions of the ICYCollapsableInputView.

When the user taps the round button on the ICYHeaderView, Ithe ICYCollapsableInputView is supposed to expand in height, pushing down the UITableView. I have the ICYCollapsableInputView expanding and collapsing, but I can't figure out how to get the UITableView to respond to the changes.  (See Animation)

I colored the main view in the xib with a RED background and the view I added in it with a BLUE background (see screenshot)

I can resize the ICYCollapsableInputView (as seen in the code and animation) using its own height constraint, but the UITableView constraint seems to ignore it.

Here is the code from ICYCollapsableInputView:

class ICYCollapsableInputView: UIView {

var view: UIView!

@IBOutlet weak var heightConstraint: NSLayoutConstraint!

@IBInspectable public var collapsedHeight: CGFloat = 150 {
    didSet {
        self.heightConstraint.constant = collapsedHeight
    }
}
@IBInspectable public var expandedHeight: CGFloat = 250 {
    didSet {
        self.heightConstraint.constant = expandedHeight
    }
}

// MARK: - Init

func loadFromNib() -> UIView {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: "ICYCollapsableInputView", bundle: bundle)
    let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView

    return view
}

override init(frame: CGRect) {
    // 1. setup any properties here

    // 2. call super.init(frame:)
    super.init(frame: frame)
    // 3. Setup view from .xib file
    xibSetup()

}

required init?(coder aDecoder: NSCoder) {
    // 1. setup any properties here

    // 2. call super.init(coder:)
    super.init(coder: aDecoder)
    // 3. Setup view from .xib file
    xibSetup()
}

func xibSetup() {
    view = loadFromNib()
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(view)
    self.heightConstraint.constant = self.collapsedHeight
    var rect = self.frame
    rect.size.height = self.collapsedHeight
    self.frame = rect
    self.view.frame = rect

}

func revealInputView() {
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
        var rect = self.frame
        rect.size.height = self.expandedHeight
        self.frame = rect
        self.heightConstraint.constant = self.expandedHeight
        self.view.layoutIfNeeded()
    }, completion: nil)
}

func closeInputView() {
    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {
        self.heightConstraint.constant = self.collapsedHeight
        var rect = self.frame
        rect.size.height = self.collapsedHeight
        self.frame = rect
        self.view.layoutIfNeeded()
    }, completion: nil)

}

 }

Body:
All you need ia just changing the height constraints.

    func revealInputView() {
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {

            self.heightConstraint.constant = self.expandedHeight //or 250
            self.view.layoutIfNeeded()
        }, completion: nil)
    }

    func closeInputView() {
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseInOut, animations: {

            self.heightConstraint.constant = self.collapsedHeight //or 150
self.view.layoutIfNeeded()
        }, completion: nil)
}

And Constraints in Storyboard should be following

for inputVW

Trailaing space to superview - 0 , leading space to superview - 0, top space to superview - 0 , bottom space to tableview - 0

for TableView

top space to inputVw - 0, leading space to superview - 0, trailing space to super view - 0, bottom space to superview - 0


问:
log4j not writing into file but its writing into console
i am aritinga small application in Linux based system where i am using slf4j libraries for logger

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

i could see the logs are visible in console but not appending to log files.

```<code><appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
    <param name="threshold" value="INFO" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%d{ABSOLUTE}][%-5p][%-10t]%m%n" />
    </layout>
</appender>

<!-- EXAMPLE logging setup NOTES: 1. files are written to "./logs/<filename>".
    You must setup the environment so that ./logs is a symlink to the correct
    location according to the EXAMPLE log standard. For example, "/opt/logs/".
    If that's not possible, change the File setting in each appender appropriately. -->

<appender name="EXAMPLE_AUDIT" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="INFO" />
    <param name="File" value="./logs/audit.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="20" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_AUDIT" />
    </layout>
</appender>

<appender name="EXAMPLE_METRIC" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="DEBUG" />
    <param name="File" value="./logs/metric.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="10" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_METRIC" />
    </layout>
</appender>

<appender name="EXAMPLE_ERROR" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="ERROR" />    <!-- only WARN and ERROR are allowed in this log -->
    <param name="File" value="./logs/error.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="10" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_ERROR" />
    </layout>
</appender>

<appender name="EXAMPLE_DEBUG" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="DEBUG" />
    <param name="File" value="./logs/debug.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="20" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_DEBUG" />
    </layout>
</appender>

<logger name="com.rsg.EXAMPLE.audit" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_AUDIT" />
</logger>

<logger name="com.rsg.EXAMPLE.metrics" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_METRIC" />
</logger>

<logger name="com.rsg.EXAMPLE.error" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
</logger>

<logger name="com.rsg.EXAMPLE.debug" additivity="false">
    <level value="info" />
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="EXAMPLE_DEBUG" />
</logger>

<root>
    <level value="DEBUG" />
    <appender-ref ref="EXAMPLE_DEBUG" />
    <appender-ref ref="CONSOLE" />

</root>

<logger name="org.openEXAMPLE.agcp.commonFunction.input"
    additivity="false">
    <level value="INFO" />
    <appender-ref ref="CONSOLE" />
</logger>

<logger name="org.openEXAMPLE.agcp.commonFunction.output"
    additivity="false">
    <level value="INFO" />
    <appender-ref ref="CONSOLE" />

</logger>

<logger name="org.openEXAMPLE.agcp.commonFunction.error"
    additivity="false">
    <level value="DEBUG" />
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="EXAMPLE_ERROR" />
</logger>

<!-- The EXAMPLE logging standard has four specific classes of logging that
    are unrelated to subsystem logger names. If you want them activated, uncomment
    this block. -->
<logger name="com.rsg.EXAMPLE.audit" additivity="false">
    <level value="info" />
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="EXAMPLE_AUDIT" />
</logger>

<logger name="com.rsg.EXAMPLE.metrics" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_METRIC" />
</logger>

<logger name="com.rsg.EXAMPLE.error" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
</logger>

<logger name="com.rsg.EXAMPLE.debug" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_DEBUG" />
</logger>

<logger name="com.rsg.ova.apiClient.http.HttpClient" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
    <appender-ref ref="CONSOLE" />
</logger>

<logger name="com.rsg.ova.roman.client.impl.romanSimplerBatchPublisher"
    additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
    <appender-ref ref="CONSOLE" />
</logger>
</code>```

答:
I have checked your logback.xml file configuration. It seems that the root tag("configuration") is missing. Can you add and check it?.

Refer https://logback.qos.ch/manual/configuration.html

Body:
i am aritinga small application in Linux based system where i am using slf4j libraries for logger

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

i could see the logs are visible in console but not appending to log files.

<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
    <param name="threshold" value="INFO" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="[%d{ABSOLUTE}][%-5p][%-10t]%m%n" />
    </layout>
</appender>

<appender name="EXAMPLE_AUDIT" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="INFO" />
    <param name="File" value="./logs/audit.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="20" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_AUDIT" />
    </layout>
</appender>

<appender name="EXAMPLE_METRIC" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="DEBUG" />
    <param name="File" value="./logs/metric.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="10" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_METRIC" />
    </layout>
</appender>

<appender name="EXAMPLE_ERROR" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="ERROR" />
    <param name="File" value="./logs/error.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="10" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_ERROR" />
    </layout>
</appender>

<appender name="EXAMPLE_DEBUG" class="org.apache.log4j.RollingFileAppender">
    <param name="threshold" value="DEBUG" />
    <param name="File" value="./logs/debug.log" />
    <param name="MaxFileSize" value="128MB" />
    <param name="MaxBackupIndex" value="20" />
    <layout class="com.rsg.ova.logging.log4j.EXAMPLELayout">
        <param name="ConversionPattern" value="EXAMPLE_DEBUG" />
    </layout>
</appender>

<logger name="com.rsg.EXAMPLE.audit" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_AUDIT" />
</logger>

<logger name="com.rsg.EXAMPLE.metrics" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_METRIC" />
</logger>

<logger name="com.rsg.EXAMPLE.error" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
</logger>

<logger name="com.rsg.EXAMPLE.debug" additivity="false">
    <level value="info" />
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="EXAMPLE_DEBUG" />
</logger>

<root>
    <level value="DEBUG" />
    <appender-ref ref="EXAMPLE_DEBUG" />
    <appender-ref ref="CONSOLE" />

</root>

<logger name="org.openEXAMPLE.agcp.commonFunction.input"
    additivity="false">
    <level value="INFO" />
    <appender-ref ref="CONSOLE" />
</logger>

<logger name="org.openEXAMPLE.agcp.commonFunction.output"
    additivity="false">
    <level value="INFO" />
    <appender-ref ref="CONSOLE" />

</logger>

<logger name="org.openEXAMPLE.agcp.commonFunction.error"
    additivity="false">
    <level value="DEBUG" />
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="EXAMPLE_ERROR" />
</logger>

<logger name="com.rsg.EXAMPLE.audit" additivity="false">
    <level value="info" />
    <appender-ref ref="CONSOLE" />
    <appender-ref ref="EXAMPLE_AUDIT" />
</logger>

<logger name="com.rsg.EXAMPLE.metrics" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_METRIC" />
</logger>

<logger name="com.rsg.EXAMPLE.error" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
</logger>

<logger name="com.rsg.EXAMPLE.debug" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_DEBUG" />
</logger>

<logger name="com.rsg.ova.apiClient.http.HttpClient" additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
    <appender-ref ref="CONSOLE" />
</logger>

<logger name="com.rsg.ova.roman.client.impl.romanSimplerBatchPublisher"
    additivity="false">
    <level value="info" />
    <appender-ref ref="EXAMPLE_ERROR" />
    <appender-ref ref="CONSOLE" />
</logger>


问:
RecyclerView/db not updated after closing activity
In one activity, I'm updating my db. I check to make sure the db is updated and finish() that activity. But when I'm on the previous activity, my db isn't updated and as a result my recyclerview is also not updated. Any ideas why?

Also, database call is in my onResume.

Oh one more key detail, it ends up updating, if I leave the activity and come back to it.

答:
You have to call notifyDataSetChanged() in onResume() in Activity 1, where you have your RecyclerView. But that is not the good approach. Everytime you will minimalize your activity and make it active again onReceive() will always be called even if your database is not updated.

All you have to do is to use startActivityForResult() from Activity 1 like this:

```<code>Intent i = new Intent(Activity1.this, Activity2.class);
startActivityForResult(i, DB_UPDATE_REQUEST);
</code>```

where DB_UPDATE_REQUEST is declared in Activity 1 like this f.e.:

```<code>public static final int DB_UPDATE_REQUEST = 1;
</code>```

In Activity 2 after you update your database create Intent, set it's result to RESULT_OK if database was updated succesfully or to RESULT_CANCELED if database update was cancelled or interrupted like this:

```<code>if (your_db_update_status) {
    setResult(AppCompatActivity.RESULT_OK);
} else {
    setResult(AppCompatActivity.RESULT_CANCELED);
}
finish();
</code>```

In Activity 1 retrieve information sent by Activity 2 like this:

```<code>@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == DB_UPDATE_REQUEST) {
        switch (resultCode) {
            case RESULT_OK: {
                Log.i("Activity 1", "Back from Activity 2. DB succesfully updated.");
                adapter.notifyDataSetChanged();
                break;
            }
            case RESULT_CANCELED: {
                Log.i("Activity 1", "Back from Activity 2. Error in updateing DB.");
                break;
            }
        }
    }
}
</code>```

Body:
You have to call notifyDataSetChanged() in onResume() in Activity 1, where you have your RecyclerView. But that is not the good approach. Everytime you will minimalize your activity and make it active again onReceive() will always be called even if your database is not updated.

All you have to do is to use startActivityForResult() from Activity 1 like this:

Intent i = new Intent(Activity1.this, Activity2.class);
startActivityForResult(i, DB_UPDATE_REQUEST);

where DB_UPDATE_REQUEST is declared in Activity 1 like this f.e.:

public static final int DB_UPDATE_REQUEST = 1;

In Activity 2 after you update your database create Intent, set it's result to RESULT_OK if database was updated succesfully or to RESULT_CANCELED if database update was cancelled or interrupted like this:

if (your_db_update_status) {
    setResult(AppCompatActivity.RESULT_OK);
} else {
    setResult(AppCompatActivity.RESULT_CANCELED);
}
finish();

In Activity 1 retrieve information sent by Activity 2 like this:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == DB_UPDATE_REQUEST) {
        switch (resultCode) {
            case RESULT_OK: {
                Log.i("Activity 1", "Back from Activity 2. DB succesfully updated.");
                adapter.notifyDataSetChanged();
                break;
            }
            case RESULT_CANCELED: {
                Log.i("Activity 1", "Back from Activity 2. Error in updateing DB.");
                break;
            }
        }
    }
}


问:
Message from debugger: Terminated due to memory issue
My app working with Geojson file. I use MapBox SDK to add MGLPolyline to map. But the problem is my file too large, so that the app crash and got the error: Message from debugger: Terminated due to memory issue. I faced with 66234 objects at first loop. I tried to chunk the array to new array but not success. Please help me to solve the prolem. Here is my code for draw on map and here is my test project on github use Xcode 8.1 If have any different 3rd party which can solve my prolems is welcome too:

```<code>func drawPolyline() {

    // Parsing GeoJSON can be CPU intensive, do it on a background thread
    DispatchQueue.global(qos: .background).async {
        // Get the path for example.geojson in the app's bundle
        let jsonPath = Bundle.main.path(forResource: "KMLMAPNew", ofType: "json")
        let jsonData = NSData(contentsOfFile: jsonPath!)

        do {
            // Load and serialize the GeoJSON into a dictionary filled with properly-typed objects
            guard let jsonDict = try JSONSerialization.jsonObject(with: jsonData! as Data, options: []) as? Dictionary<String, AnyObject>, let features = jsonDict["features"] as? Array<AnyObject> else{return}

            for feature in features {
                guard let feature = feature as? Dictionary<String, AnyObject>, let geometry = feature["geometry"] as? Dictionary<String, AnyObject> else{ continue }

                if geometry["type"] as? String == "LineString" {
                    // Create an array to hold the formatted coordinates for our line
                    var coordinates: [CLLocationCoordinate2D] = []

                    if let locations = geometry["coordinates"] as? Array<AnyObject> {
                        // Iterate over line coordinates, stored in GeoJSON as many lng, lat arrays
                        for location in locations {
                            // Make a CLLocationCoordinate2D with the lat, lng
                            if let location = location as? Array<AnyObject>{
                                let coordinate = CLLocationCoordinate2DMake(location[1].doubleValue, location[0].doubleValue)

                                // Add coordinate to coordinates array
                                coordinates.append(coordinate)
                            }
                        }
                    }

                    let line = MGLPolyline(coordinates: &coordinates, count: UInt(coordinates.count))

                    // Optionally set the title of the polyline, which can be used for:
                    //  - Callout view
                    //  - Object identification
                    line.title = "Crema to Council Crest"

                    // Add the annotation on the main thread
                    DispatchQueue.main.async {
                        // Unowned reference to self to prevent retain cycle
                        [unowned self] in
                        self.mapboxView.addAnnotation(line)
                    }
                }
            }
        }
        catch
        {
            print("GeoJSON parsing failed")
        }
    }
}
</code>```

EDIT::@Alessandro Ornano and @fragilecat thanks so much. But those solutions still cannot solve the terminate of the app on iPad. I think it so hard to change the current code to get it to work properly, because the data is so large. I think I will need another solution that works with big data. Like chunking the array into the small arrays then loading them by queue. But I don't know how to start :(

I send an email to the support team at MapBox, asking for suggestions.

答:
make you stuff  on callout this means execute polyne only when click on the pin
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView)</p>

Body:
My app working with Geojson file. I use MapBox SDK to add MGLPolyline to map. But the problem is my file too large, so that the app crash and got the error: Message from debugger: Terminated due to memory issue. I faced with 66234 objects at first loop. I tried to chunk the array to new array but not success. Please help me to solve the prolem. Here is my code for draw on map and here is my test project on github use Xcode 8.1 If have any different 3rd party which can solve my prolems is welcome too:

func drawPolyline() {

    // Parsing GeoJSON can be CPU intensive, do it on a background thread
    DispatchQueue.global(qos: .background).async {
        // Get the path for example.geojson in the app's bundle
        let jsonPath = Bundle.main.path(forResource: "KMLMAPNew", ofType: "json")
        let jsonData = NSData(contentsOfFile: jsonPath!)

        do {
            // Load and serialize the GeoJSON into a dictionary filled with properly-typed objects
            guard let jsonDict = try JSONSerialization.jsonObject(with: jsonData! as Data, options: []) as? Dictionary<String, AnyObject>, let features = jsonDict["features"] as? Array<AnyObject> else{return}

            for feature in features {
                guard let feature = feature as? Dictionary<String, AnyObject>, let geometry = feature["geometry"] as? Dictionary<String, AnyObject> else{ continue }

                if geometry["type"] as? String == "LineString" {
                    // Create an array to hold the formatted coordinates for our line
                    var coordinates: [CLLocationCoordinate2D] = []

                    if let locations = geometry["coordinates"] as? Array<AnyObject> {
                        // Iterate over line coordinates, stored in GeoJSON as many lng, lat arrays
                        for location in locations {
                            // Make a CLLocationCoordinate2D with the lat, lng
                            if let location = location as? Array<AnyObject>{
                                let coordinate = CLLocationCoordinate2DMake(location[1].doubleValue, location[0].doubleValue)

                                // Add coordinate to coordinates array
                                coordinates.append(coordinate)
                            }
                        }
                    }

                    let line = MGLPolyline(coordinates: &coordinates, count: UInt(coordinates.count))

                    // Optionally set the title of the polyline, which can be used for:
                    //  - Callout view
                    //  - Object identification
                    line.title = "Crema to Council Crest"

                    // Add the annotation on the main thread
                    DispatchQueue.main.async {
                        // Unowned reference to self to prevent retain cycle
                        [unowned self] in
                        self.mapboxView.addAnnotation(line)
                    }
                }
            }
        }
        catch
        {
            print("GeoJSON parsing failed")
        }
    }
}

EDIT::@Alessandro Ornano and @fragilecat thanks so much. But those solutions still cannot solve the terminate of the app on iPad. I think it so hard to change the current code to get it to work properly, because the data is so large. I think I will need another solution that works with big data. Like chunking the array into the small arrays then loading them by queue. But I don't know how to start :(

I send an email to the support team at MapBox, asking for suggestions.


问:
survey php mysql counter
I am working on a small php/mysql survey.
I have all my questions/answers/cateogries stored in a mysql db.
I also have my categories stored in an array in my php script.
categories array=("Person","A Mom","A Student","Somebody",etc)
each category have 4 questions and 4 answers.
there are 8 categories. a user answers the survey by moving from category 1, to the next category etc...

here is a sql query that i have hard coded the category 2, so that i can display the 4 questions that is associated with category 2:
select a., b. from category a, questions b where a.id = b.id and a.id='2'

my question is, i will like to make the number "2" dynamic. dynamic here means, when the user click on the "NEXT" button, i would like to the new sql query to be like this:

select a., b. from category a, questions b where a.id = b.id and a.id='3'

clicking on next button again goes to:
select a., b. from category a, questions b where a.id = b.id and a.id='4'
etc...

below is a code snippet:

```<code> <?php
    $categories = array ("Person","A Mom","A Student","Somebody");

    $sql="select a.*, b.* from category a, questions b where a.id = b.id and a.id='2'";
    $result=mysql_query($sql,$db_connection);
    if (!$result)
    {
   die('Error: ' . mysql_error());
    }
 ?>
  <tr>
    <td height="32" colspan="5" bgcolor="#ECA4DD"><b><?php echo $result['name'];?></b></td></tr>
  <tr>
  <tr>
    <td colspan="5" class="content_2"><?php echo $result['description'];?></td>
  </tr>
  <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">

     <?php
    while ($row = mysql_fetch_assoc($result))
    {

 ?>

   <tr>
    <td class="content_2"><?php echo "Question1"; ?></td>
    <td align="center" valign="middle"><input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> Rare </td>
    <td align="center" valign="middle"><input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> Sometimes</td>
    <td align="center" valign="middle"><input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> True</td>
    <td align="center" valign="middle"><input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> Always</td>
  </tr>
  <tr>
       <td height="108"></td>
       <td align="center" valign="middle"> </td>
       <td align="center" valign="middle"> </td>
       <td colspan="2" align="right" valign="middle"><input type="submit" name="save" value="NextButton"/>
       </td>
      </tr>

   <?php
   mysql_free_result($result);
   }
  ?>

 </form>
</code>```

答:
You can pass the current question number via $_GET variables or something of that nature. So at the start of the page grab the current question:

```<code>$current_question = isset($_GET['current_question']) ? $_GET['current_question'] : '1';
</code>```

And then in your query you can run something like:

```<code>$sql = "SELECT `a`.*, `b`.* FROM `category` AS `a`, `questions` AS `b` WHERE `a`.`id` = `b`.`id` AND `a`.`id` = '{$current_question}'";
</code>```

Title: survey php mysql counter

Body:
I am working on a small php/mysql survey.
I have all my questions/answers/cateogries stored in a mysql db.
I also have my categories stored in an array in my php script.
categories array=("Person","A Mom","A Student","Somebody",etc)
each category have 4 questions and 4 answers.
there are 8 categories. a user answers the survey by moving from category 1, to the next category etc...

here is a sql query that i have hard coded the category 2, so that i can display the 4 questions that is associated with category 2:
select a., b. from category a, questions b where a.id = b.id and a.id='2'

my question is, i will like to make the number "2" dynamic. dynamic here means, when the user click on the "NEXT" button, i would like to the new sql query to be like this:

select a., b. from category a, questions b where a.id = b.id and a.id='3'

clicking on next button again goes to:
select a., b. from category a, questions b where a.id = b.id and a.id='4'
etc...

below is a code snippet:

 <?php
    $categories = array ("Person","A Mom","A Student","Somebody");

    $sql="select a.*, b.* from category a, questions b where a.id = b.id and a.id='2'";
    $result=mysql_query($sql,$db_connection);
    if (!$result)
    {
   die('Error: ' . mysql_error());
    }
 ?>

    <?php echo $result['name'];?>

    <?php echo $result['description'];?>

  <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">

     <?php
    while ($row = mysql_fetch_assoc($result))
    {

 ?>

    <?php echo "Question1"; ?>
    <input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> Rare
    <input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> Sometimes
    <input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> True
    <input type="radio" name="q1" id="s1" value="<?php echo $row['q1']; ?>"/> Always

       <input type="submit" name="save" value="NextButton"/>

   <?php
   mysql_free_result($result);
   }
  ?>

 </form>

Body:
You can pass the current question number via $_GET variables or something of that nature. So at the start of the page grab the current question:

$current_question = isset($_GET['current_question']) ? $_GET['current_question'] : '1';

And then in your query you can run something like:

$sql = "SELECT `a`.*, `b`.* FROM `category` AS `a`, `questions` AS `b` WHERE `a`.`id` = `b`.`id` AND `a`.`id` = '{$current_question}'";


问:
JAVA_HOME is set to an invalid directory
I'm working with gradle and trying to deploy my JAVAFX application into .apk

If i run my gradle command it says that my JAVA_HOME is set to an invalid directory.

It is set to C:\Program Files\Java\javaversion\bin
(there is an actual version actually, but it isn't necessery atm)
And the same is at the environment variable.

Any ideas, why i'm getting this error?

答: @charen You are right. Gradle, as of its last version 3.4.1, only works with Java 32 bits. So  your JAVA_HOME shoud point to the Java JRE at Program Files (x86).


问:
Constructor: is it the right one being called?
In your opinion, which constructor will be called?

```<code>class Element {
public:
    Element(bool b = true, bool c = true);
    Element(const std::string s, bool b = true, bool c = true);
};
...
Element element("something", true);
</code>```

Wrong! The first one.

Do I have to restart Stroustrup's book from the beginning?

I tried without the const, but nothing changes.

It seems that a char* looks more like a bool than a std::string.

With this code everything is all right:

```<code>Element element(string("something"), true);
</code>```

Compiler: Microsoft Visual C++ 2010

OS: Windows 7

答:
There is a built-in conversion from pointer types to bool, non-null pointers are converted to true and null pointer values to false.

std::string is a user-defined type (in the loosest sense of the word user) so the conversion from const char* to std::string won't be preferred over the built-in const char* to bool conversion. You have to do something like this (or add an overload which takes a const char *).

```<code>Element element( std::string("something"), true);
</code>```

Body:
In your opinion, which constructor will be called?

class Element {
public:
    Element(bool b = true, bool c = true);
    Element(const std::string s, bool b = true, bool c = true);
};
...
Element element("something", true);

Wrong! The first one.

Do I have to restart Stroustrup's book from the beginning?

I tried without the const, but nothing changes.

It seems that a char* looks more like a bool than a std::string.

With this code everything is all right:

Element element(string("something"), true);

Compiler: Microsoft Visual C++ 2010

OS: Windows 7

Body:
There is a built-in conversion from pointer types to bool, non-null pointers are converted to true and null pointer values to false.

std::string is a user-defined type (in the loosest sense of the word user) so the conversion from const char* to std::string won't be preferred over the built-in const char* to bool conversion. You have to do something like this (or add an overload which takes a const char *).

Element element( std::string("something"), true);