问:
sed: replace many lines from a file with single notification
I'm looking for a solution in GNU sed, but POSIX sed is OK and awk will be OK but probably more complicated than necessary. I prefer sed for this, it should be easy but I'm stuck. Seems like a one-liner can do this, no need to create a python/bash script or anything.

my attempted solution

```<code>  sed -i '218,226140d; 218i ...REMOVED...' psql.log
</code>```

This deletes the desired rows, but the insert gets lost. If I move the insert to line 217 I get:

```<code>  sed -i '218,226140d; 217i ...REMOVED...' psql.log
</code>```

result:

```<code>  ┌────────────┬─────────────────────┬─────────────────┐
  │ col_one    │     col_two         │ column_three    │
  ├────────────┼─────────────────────┼─────────────────┤
  │ CC00CBSNRY │           553854451 │       15003.44  │
  │ CC00CBSNRY │          1334177150 │        5159.57  │
  ...REMOVED...
  │ CC6XDSQGH2 │         42385958605 │ [null]          │ (line 217 in original file)
  │ CC6XJ8YG5C │         24661013005 │ [null]          │ (line 226141 in original file)
  │ CC6XJ9HGRG │         44946564505 │ [null]          │
  │ CC6XMQW6SJ │         34496719615 │ [null]          │
  └────────────┴─────────────────────┴─────────────────┘
</code>```

I know - this should be good enough, but I'm annoyed that I can't get this simple one-liner to work right. What am I missing?

the problem

I keep the psql.log file as a reference for work I am doing developing SQL code. It's very useful to see iterations of the query and the results.

The problem is that sometimes I forget to limit the output and the query will generate 100k+ rows of results that aren't a helpful reference, and I'd like to delete them from my file, leaving a note that reminds me the query output has been excised.

It would be nice to match the pattern, say every output more than 50 rows I could squash down to just the first 5 rows and the last 5.  However, its easy for me to mark the line numbers where I've blown up the file, so I'd be happy with just using sed to delete lines N through M, and insert the message ...REMOVED... where line N was.

Here is an example log file, added notes are in parentheses. The query text can change and the number of columns can be from 1 to 100 or more:

```<code>  ...
  ********* QUERY **********
  select      *
  from        table
  where       rnk <= 3
  **************************

  ┌────────────┬─────────────────────┬─────────────────┐
  │ col_one    │     col_two         │ column_three    │
  ├────────────┼─────────────────────┼─────────────────┤
  │ CC00CBSNRY │           553854451 │       15003.44  │
  │ CC00CBSNRY │          1334177150 │        5159.57  │
  │ CC6XDSQGH2 │         42385958605 │ [null]          │ (line 217)
  │ CC6XF2SVWT │         13182280615 │ [null]          │
  (many rows)

  │ CC6XF2XWDT │           995086081 │ [null]          │
  │ CC6XFX3TL1 │         25195177405 │ [null]          │
  │ CC6XJ8YG5C │         24661013005 │ [null]          │  (line 226141)
  │ CC6XJ9HGRG │         44946564505 │ [null]          │
  │ CC6XMQW6SJ │         34496719615 │ [null]          │
  └────────────┴─────────────────────┴─────────────────┘
  (225926 rows)

  ********* QUERY **********
  /* another query begins */

  select * from table where X = 1 limit 20;

  /* well done you remembered to limit the output */
  **************************
  ...
</code>```

acceptable output

the query text should all be untouched, and the top/bottom three rows of output kept. The annotation ...REMOVED... has been added and rows 218 through 226140 have been deleted:

```<code>  ********* QUERY **********
  select      *
  from        table
  where       rnk <= 3
  **************************

  ┌────────────┬─────────────────────┬─────────────────┐
  │ col_one    │     col_two         │ column_three    │
  ├────────────┼─────────────────────┼─────────────────┤
  │ CC00CBSNRY │           553854451 │       15003.44  │
  │ CC00CBSNRY │          1334177150 │        5159.57  │
  │ CC6XDSQGH2 │         42385958605 │ [null]          │ (line 217 in original file)
  ...REMOVED...
  │ CC6XJ8YG5C │         24661013005 │ [null]          │ (line 226141 in original file)
  │ CC6XJ9HGRG │         44946564505 │ [null]          │
  │ CC6XMQW6SJ │         34496719615 │ [null]          │
  └────────────┴─────────────────────┴─────────────────┘
  (225926 rows)

  ********* QUERY **********
  (etc just like example above)
</code>```

update

the border comes from my .psqlrc with \pset border 2

therefore solutions depending on the ┌ character are fragile but OK

over time i've learned that manually flagging the line numbers is too time consuming, so the best solution needs a pattern match

答:
The sed man page is more helpful than you might think at first glance. The [addr]c command is exactly what is needed (note the whitespace after c is ignored):

```<code>sed -i '218,226141c ...REMOVED...' psql.log
</code>```

So there is the solution for known line numbers.

Does anyone want to provide a generic solution where the line numbers aren't known? Probably awk would be the better tool but maybe sed can remove output that is too long.

Body:
I'm looking for a solution in GNU sed, but POSIX sed is OK and awk will be OK but probably more complicated than necessary. I prefer sed for this, it should be easy but I'm stuck. Seems like a one-liner can do this, no need to create a python/bash script or anything.

my attempted solution

  sed -i '218,226140d; 218i ...REMOVED...' psql.log

This deletes the desired rows, but the insert gets lost. If I move the insert to line 217 I get:

  sed -i '218,226140d; 217i ...REMOVED...' psql.log

result:

  ┌────────────┬─────────────────────┬─────────────────┐
  │ col_one    │     col_two         │ column_three    │
  ├────────────┼─────────────────────┼─────────────────┤
  │ CC00CBSNRY │           553854451 │       15003.44  │
  │ CC00CBSNRY │          1334177150 │        5159.57  │
  ...REMOVED...
  │ CC6XDSQGH2 │         42385958605 │ [null]          │ (line 217 in original file)
  │ CC6XJ8YG5C │         24661013005 │ [null]          │ (line 226141 in original file)
  │ CC6XJ9HGRG │         44946564505 │ [null]          │
  │ CC6XMQW6SJ │         34496719615 │ [null]          │
  └────────────┴─────────────────────┴─────────────────┘

I know - this should be good enough, but I'm annoyed that I can't get this simple one-liner to work right. What am I missing?

the problem

I keep the psql.log file as a reference for work I am doing developing SQL code. It's very useful to see iterations of the query and the results.

The problem is that sometimes I forget to limit the output and the query will generate 100k+ rows of results that aren't a helpful reference, and I'd like to delete them from my file, leaving a note that reminds me the query output has been excised.

It would be nice to match the pattern, say every output more than 50 rows I could squash down to just the first 5 rows and the last 5.  However, its easy for me to mark the line numbers where I've blown up the file, so I'd be happy with just using sed to delete lines N through M, and insert the message ...REMOVED... where line N was.

Here is an example log file, added notes are in parentheses. The query text can change and the number of columns can be from 1 to 100 or more:

  ...
  ********* QUERY **********
  select      *
  from        table
  where       rnk <= 3
  **************************

  ┌────────────┬─────────────────────┬─────────────────┐
  │ col_one    │     col_two         │ column_three    │
  ├────────────┼─────────────────────┼─────────────────┤
  │ CC00CBSNRY │           553854451 │       15003.44  │
  │ CC00CBSNRY │          1334177150 │        5159.57  │
  │ CC6XDSQGH2 │         42385958605 │ [null]          │ (line 217)
  │ CC6XF2SVWT │         13182280615 │ [null]          │
  (many rows)

  │ CC6XF2XWDT │           995086081 │ [null]          │
  │ CC6XFX3TL1 │         25195177405 │ [null]          │
  │ CC6XJ8YG5C │         24661013005 │ [null]          │  (line 226141)
  │ CC6XJ9HGRG │         44946564505 │ [null]          │
  │ CC6XMQW6SJ │         34496719615 │ [null]          │
  └────────────┴─────────────────────┴─────────────────┘
  (225926 rows)

  ********* QUERY **********
  /* another query begins */

  select * from table where X = 1 limit 20;

  /* well done you remembered to limit the output */
  **************************
  ...

acceptable output

the query text should all be untouched, and the top/bottom three rows of output kept. The annotation ...REMOVED... has been added and rows 218 through 226140 have been deleted:

  ********* QUERY **********
  select      *
  from        table
  where       rnk <= 3
  **************************

  ┌────────────┬─────────────────────┬─────────────────┐
  │ col_one    │     col_two         │ column_three    │
  ├────────────┼─────────────────────┼─────────────────┤
  │ CC00CBSNRY │           553854451 │       15003.44  │
  │ CC00CBSNRY │          1334177150 │        5159.57  │
  │ CC6XDSQGH2 │         42385958605 │ [null]          │ (line 217 in original file)
  ...REMOVED...
  │ CC6XJ8YG5C │         24661013005 │ [null]          │ (line 226141 in original file)
  │ CC6XJ9HGRG │         44946564505 │ [null]          │
  │ CC6XMQW6SJ │         34496719615 │ [null]          │
  └────────────┴─────────────────────┴─────────────────┘
  (225926 rows)

  ********* QUERY **********
  (etc just like example above)

update

the border comes from my .psqlrc with \pset border 2

therefore solutions depending on the ┌ character are fragile but OK

over time i've learned that manually flagging the line numbers is too time consuming, so the best solution needs a pattern match

Body:
The sed man page is more helpful than you might think at first glance. The [addr]c command is exactly what is needed (note the whitespace after c is ignored):

sed -i '218,226141c ...REMOVED...' psql.log

So there is the solution for known line numbers.

Does anyone want to provide a generic solution where the line numbers aren't known? Probably awk would be the better tool but maybe sed can remove output that is too long.


来源: stackexchange

问:
Routes and Models issue on a Rails Join Table
I'm creating an app that allows users to create custom itineraries for places in my neighborhood.  Each place is stored on a places table and is associated with a place_id.  Currently the places are associated with users through itineraries as a join table.  This works fine, but I want to allow users to sign_in and be directed to a view which will list all their itineraries.  To do this, I will need to create a new instance of an itinerary through a set of user params that has a title and is associated with a user_id.  Then, the user can add place_ids to that instance of the itinerary.  Unfortunately, I cannot wrap my head around how this should be routed in active record.  Can anyone help me figure out how to structure this, so it will work, because everything I try keeps returning the error: No route matches [GET] "/create_itinerary".

Itinerary Model

```<code>class Itinerary < ApplicationRecord
belongs_to :user
belongs_to :place
</code>```

end

Itinerary Controller

```<code>class ItinerariesController < ApplicationController
def add_place
    # current_user
    @place = Place.find(params[:id])
    @itenerary = @place.itineraries.create(user_id: current_user.id)

    redirect_to :back
end

def index
    @itinerary_places = current_user.places
end

def show
    @itinerary_places = current_user.places
end

def new
    @itinerary_new = Itinerary.new(params[:itinerary])

    redirect_to create_itinerary_path
end

def create
    itinerary = Itinerary.new(itinerary_params)
    itinerary.user_id = session[:user_id]
    itinerary.save
end

private

def itinerary_params
    params.require(:itinerary).permit(:title)
end

    end
</code>```

Ininerary (new.html.erb)

```<code><%= form_for @itinerary_new, url: {action: "create"}, html: {} do |f| %>

<%= f.text_field :title, placeholder: "Name Your New Itinerary" %>

<%= f.submit :class => "user_submit" %>
</code>```

itineraries routing

```<code>get "/itinerary_new", to: "itineraries#new"
get "/itinerary_portal", to: "itineraries#index"
get "/itinerary", to: "itineraries#show"
get "/add_place/:id", to: "itineraries#add_place"
get "/delete_itinerary", to: "itineraries#destroy"
post "/create_itinerary", to: "itinerary#create"
</code>```

The Schema

```<code>ActiveRecord::Schema.define(version: 20170402040005) do

create_table "itineraries", force: :cascade do |t|
 t.integer  "user_id"
 t.datetime "created_at", null: false
 t.datetime "updated_at", null: false
 t.integer  "place_id"
 t.string   "title"

 end
</code>```

答:
The problem is that when your visit /itinerary_new, it redirect to /create_itinerary. Then the http method mismatch, because the create_itinerary only accept post, no get.

Remove redirect_to create_itinerary_path in new action. This sentence is meaningless and wrong.

ContentLicense: CC BY-SA 3.0

Body:
I'm creating an app that allows users to create custom itineraries for places in my neighborhood.  Each place is stored on a places table and is associated with a place_id.  Currently the places are associated with users through itineraries as a join table.  This works fine, but I want to allow users to sign_in and be directed to a view which will list all their itineraries.  To do this, I will need to create a new instance of an itinerary through a set of user params that has a title and is associated with a user_id.  Then, the user can add place_ids to that instance of the itinerary.  Unfortunately, I cannot wrap my head around how this should be routed in active record.  Can anyone help me figure out how to structure this, so it will work, because everything I try keeps returning the error: No route matches [GET] "/create_itinerary".

Itinerary Model

class Itinerary < ApplicationRecord
belongs_to :user
belongs_to :place

end

Itinerary Controller

class ItinerariesController < ApplicationController
def add_place
    # current_user
    @place = Place.find(params[:id])
    @itenerary = @place.itineraries.create(user_id: current_user.id)

    redirect_to :back
end

def index
    @itinerary_places = current_user.places
end

def show
    @itinerary_places = current_user.places
end

def new
    @itinerary_new = Itinerary.new(params[:itinerary])

    redirect_to create_itinerary_path
end

def create
    itinerary = Itinerary.new(itinerary_params)
    itinerary.user_id = session[:user_id]
    itinerary.save
end

private

def itinerary_params
    params.require(:itinerary).permit(:title)
end

    end

Ininerary (new.html.erb)

<%= form_for @itinerary_new, url: {action: "create"}, html: {} do |f| %>

<%= f.text_field :title, placeholder: "Name Your New Itinerary" %>

<%= f.submit :class => "user_submit" %>

itineraries routing

get "/itinerary_new", to: "itineraries#new"
get "/itinerary_portal", to: "itineraries#index"
get "/itinerary", to: "itineraries#show"
get "/add_place/:id", to: "itineraries#add_place"
get "/delete_itinerary", to: "itineraries#destroy"
post "/create_itinerary", to: "itinerary#create"

The Schema

ActiveRecord::Schema.define(version: 20170402040005) do

create_table "itineraries", force: :cascade do |t|
 t.integer  "user_id"
 t.datetime "created_at", null: false
 t.datetime "updated_at", null: false
 t.integer  "place_id"
 t.string   "title"

 end


问:
JOptionPane.showOptionDialog does not always move to front in Applet
I have a JOptionPane popup in my applet normally, a-la:

```<code>      Object[] options = {"Grade", "Save", "Cancel"};
      selection = JOptionPane.showOptionDialog(this,
      "Do you want to grade now or save your work to continue later?",
      "Grade Or Save",
      JOptionPane.DEFAULT_OPTION,
      JOptionPane.QUESTION_MESSAGE,
      null,
      options,
      options[2]);
</code>```

this refers to the JApplet object.

The popup works fine and everything, but occasionally it will appear behind the applet instead of popping up in front of it.

答:
The thing to do is find the parent of the applet that is a Frame (it's of a hidden, plugin specific type) and use that frame as the dialog owner. You can find that with (Frame)SwingUtilities.getAncestorOfClass(java.awt.Frame.class, theApplet);

That will ensure the dialog remains on top of the browser. However, if the user switches browser tabs, the dialog doesn't hide.

ContentLicense: CC BY-SA 2.5

Body:
I have a JOptionPane popup in my applet normally, a-la:

      Object[] options = {"Grade", "Save", "Cancel"};
      selection = JOptionPane.showOptionDialog(this,
      "Do you want to grade now or save your work to continue later?",
      "Grade Or Save",
      JOptionPane.DEFAULT_OPTION,
      JOptionPane.QUESTION_MESSAGE,
      null,
      options,
      options[2]);

this refers to the JApplet object.

The popup works fine and everything, but occasionally it will appear behind the applet instead of popping up in front of it.


问:
how to host webapplication and webapi in single solution
I created a solution with two webapplication project. One is asp.net mvc and second one is web api. Now I want to publish. Kindly suggest me how to publish my webapplication and webapi</p>

答: all mvc pages, web api controllers and aspx pages can be added to single project, no need to different project, if you need to seperate business you can use areas and class libraries </p>


问:
Image segmentation using kmeans algorithm in java
I am making java application that will detect the plant disease using image processing and neural network. But I am facing problem in segmenting the image based on the k-means algorithm in java. Actually I do not have idea how to segment the image. Please if somebody can help me with source code to segment the image in different clusters. Thank you</p>

答:
This link below is a good example.It basically talks about how to implement Kmeans segmentation to compress image step by step.
http://popscan.blogspot.com/2013/06/image-segmentation-with-k-means.html</p>


问:
Cardview shadow not appearing in lollipop devices?
Am using the cardview in my android app. However the shadow is not showing. Here is the xml layout

The default optionsmenu shadow also not showing.

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ECEDF0"
    android:orientation="vertical" >

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:clipChildren="false"
        card_view:cardBackgroundColor="@color/white"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="14dp"
        card_view:cardUseCompatPadding="true" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:text="Google Play" />
    </android.support.v7.widget.CardView>

</LinearLayout>
</code>```

答:
for someone ,

one other thing that you should be aware of, shadows will not show if you have this line in the manifest:

android:hardwareAccelerated="false"

I tried all of the suggested stuff but it only worked for me when i removed the line, the reason i had the line was because my app works with a number of bitmap images and they were causing the app to crash.

Body:
Am using the cardview in my android app. However the shadow is not showing. Here is the xml layout

The default optionsmenu shadow also not showing.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ECEDF0"
    android:orientation="vertical" >

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:clipChildren="false"
        card_view:cardBackgroundColor="@color/white"
        card_view:cardCornerRadius="4dp"
        card_view:cardElevation="14dp"
        card_view:cardUseCompatPadding="true" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:text="Google Play" />
    </android.support.v7.widget.CardView>

</LinearLayout>


问:
ggplot2: reorder bars from highest to lowest in each facet
In the df below, I want to reorder bars from highest to lowest in each facet

I tried

```<code>df <- df %>% tidyr::gather("var", "value", 2:4)
ggplot(df, aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity")+facet_wrap(~var, ncol =3)
</code>```

It gave me

It didn't order the bars from highest to lowest in each facet.

I figured out another way to get what I want. I had to plot each variable at a time, then combine all plots using grid.arrange()

```<code>#I got this function from @eipi10's answer
#http://stackoverflow.com/questions/38637261/perfectly-align-several-plots/38640937#38640937
#Function to extract legend
# https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot) {
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend)
}

p1 <- ggplot(df[df$var== "A", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)

fin_legend <- g_legend(p1)
p1 <- p1 + guides(fill= F)

p2 <- ggplot(df[df$var== "B", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE)

p3 <- ggplot(df[df$var== "C", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE)

grid.arrange(p1, p2, p3, fin_legend, ncol =4, widths = c(1.5, 1.5, 1.5, 0.5))
</code>```

The result is what I want

I wonder if there is a straightforward way that can help me order the bars from highest to lowest in all facets without having to plot each variable separtely and then combine them. Any suggestions will be much appreciated.

DATA

```<code>df <-  read.table(text = c("
id  A   B   C
site1   10  15  20
site2   20  10  30
site3   30  20  25
site4   40  35  40
site5   50  30  35"), header = T)
</code>```

答:
If you're willing to lose the X axis labels, you can do this by using the actual y values as the x aesthetic, then dropping unused factor levels in each facet:

```<code>ggplot(df, aes (x = factor(-value), y = value, fill = id))+
    geom_bar(stat="identity", na.rm = TRUE)+
    facet_wrap(~var, ncol =3, scales = "free_x", drop = TRUE) +
    theme(
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank()
    )
</code>```

Result:

The loss of x-axis labels is probably not too bad here as you still have the colours to go on (and the x-axis is confusing anyway since it's not consistent across facets).

Body:
In the df below, I want to reorder bars from highest to lowest in each facet

I tried

df <- df %>% tidyr::gather("var", "value", 2:4)
ggplot(df, aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity")+facet_wrap(~var, ncol =3)

It gave me

It didn't order the bars from highest to lowest in each facet.

I figured out another way to get what I want. I had to plot each variable at a time, then combine all plots using grid.arrange()

#I got this function from @eipi10's answer
#http://stackoverflow.com/questions/38637261/perfectly-align-several-plots/38640937#38640937
#Function to extract legend
# https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot) {
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend)
}

p1 <- ggplot(df[df$var== "A", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)

fin_legend <- g_legend(p1)
p1 <- p1 + guides(fill= F)

p2 <- ggplot(df[df$var== "B", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE)

p3 <- ggplot(df[df$var== "C", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE)

grid.arrange(p1, p2, p3, fin_legend, ncol =4, widths = c(1.5, 1.5, 1.5, 0.5))

The result is what I want

I wonder if there is a straightforward way that can help me order the bars from highest to lowest in all facets without having to plot each variable separtely and then combine them. Any suggestions will be much appreciated.

DATA

df <-  read.table(text = c("
id  A   B   C
site1   10  15  20
site2   20  10  30
site3   30  20  25
site4   40  35  40
site5   50  30  35"), header = T)

Body:
If you're willing to lose the X axis labels, you can do this by using the actual y values as the x aesthetic, then dropping unused factor levels in each facet:

ggplot(df, aes (x = factor(-value), y = value, fill = id))+
    geom_bar(stat="identity", na.rm = TRUE)+
    facet_wrap(~var, ncol =3, scales = "free_x", drop = TRUE) +
    theme(
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank()
    )

Result:

The loss of x-axis labels is probably not too bad here as you still have the colours to go on (and the x-axis is confusing anyway since it's not consistent across facets).


问:
Get SSID of the wireless network I am connected to with C# .Net on Windows Vista
I'd like to know if there is any .Net class that allows me to know the SSID of the wireless network I'm connected to.
So far I only found the library linked below. Is the best I can get or should I use something else?
Managed WiFi (http://www.codeplex.com/managedwifi)

The method that exploits WMI works for Windows XP but is it not working anymore with Windows Vista.

答:
It looks like this will do what you want:

```<code>ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSNdis_80211_ServiceSetIdentifier");

foreach (ManagementObject queryObj in searcher.Get())
{
    Console.WriteLine("-----------------------------------");
    Console.WriteLine("MSNdis_80211_ServiceSetIdentifier instance");
    Console.WriteLine("-----------------------------------");

    if(queryObj["Ndis80211SsId"] == null)
        Console.WriteLine("Ndis80211SsId: {0}",queryObj["Ndis80211SsId"]);
    else
    {
        Byte[] arrNdis80211SsId = (Byte[])
        (queryObj["Ndis80211SsId"]);
        foreach (Byte arrValue in arrNdis80211SsId)
        {
            Console.WriteLine("Ndis80211SsId: {0}", arrValue);
        }
    }
}
</code>```

from http://bytes.com/groups/net-c/657473-wmi-wifi-discovery

OwnerDisplayName: wisher

LastEditorDisplayName: wisher

Body:
It looks like this will do what you want:

ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSNdis_80211_ServiceSetIdentifier");

foreach (ManagementObject queryObj in searcher.Get())
{
    Console.WriteLine("-----------------------------------");
    Console.WriteLine("MSNdis_80211_ServiceSetIdentifier instance");
    Console.WriteLine("-----------------------------------");

    if(queryObj["Ndis80211SsId"] == null)
        Console.WriteLine("Ndis80211SsId: {0}",queryObj["Ndis80211SsId"]);
    else
    {
        Byte[] arrNdis80211SsId = (Byte[])
        (queryObj["Ndis80211SsId"]);
        foreach (Byte arrValue in arrNdis80211SsId)
        {
            Console.WriteLine("Ndis80211SsId: {0}", arrValue);
        }
    }
}

from http://bytes.com/groups/net-c/657473-wmi-wifi-discovery

OwnerDisplayName: amdfan


问:
Java Exceptions: exception myException is never thrown in body of corresponding try statement
I understand the idea of this error. But I guess I don't understand how this works down the call stack.

File Main.java:

```<code>public static void main(String[] args) {
    try {
         Function1();
      } catch (myException e) {
      System.out.println(e.getMessage());
    }
}
public static void Function1() {
    Function2();
}
</code>```

Function2 exists in another file:

File2.java

```<code>public void Function2() throws myException {
     ....
}
</code>```

So through several calls (down the call stack) I have Function2 which specifies the requirement "throws myException". How come the main function (where the error is being directed at) doesn't recognize that I throw myException down the line?

Any guidance in where the 'hole' in my "exception knowledge" lies would be greatly appreciated.

aitee,

答: Your problem is that Function1() does not declare that it throws myException - which means that there should be 2 compile errors: one about the exception not being caught or declared, and one about catching the exception that is not declared.

Body:
I understand the idea of this error. But I guess I don't understand how this works down the call stack.

File Main.java:

public static void main(String[] args) {
    try {
         Function1();
      } catch (myException e) {
      System.out.println(e.getMessage());
    }
}
public static void Function1() {
    Function2();
}

Function2 exists in another file:

File2.java

public void Function2() throws myException {
     ....
}

So through several calls (down the call stack) I have Function2 which specifies the requirement "throws myException". How come the main function (where the error is being directed at) doesn't recognize that I throw myException down the line?

Any guidance in where the 'hole' in my "exception knowledge" lies would be greatly appreciated.

aitee,


问:
Android Studio, How to generate ExpandableListView from JSON volley?
can anyone help me?
i try to make expandablelistview where the data from server by using POST method. but i got error :
'int java.util.List.size()' on a null object reference
here is my code

private ExpandableListView listView;
    private ExpandableListAdapter listAdapter;
    private List<String> listDataHeader;
    private HashMap<String, List<String>> listHash;
    Button btnSearch;
    EditText search;
    String kata;
    String statutory_url = "http://ds.bki.co.id:7777/ds/android/datasurvey.php";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnSearch = (Button) findViewById(R.id.btnSearch);
        search = (EditText) findViewById(R.id.editText);
        listView = (ExpandableListView) findViewById(R.id.ExpList);

        btnSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                kata = search.getText().toString();
                getData();
            }
        });
        listAdapter = new ExpandableListAdapter(this,listDataHeader,listHash);
        listView.setAdapter(listAdapter);
    }

    private void getData(){
        RequestQueue queue = Volley.newRequestQueue(this.getApplicationContext());
        StringRequest stringRequest = new StringRequest(Request.Method.POST, statutory_url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                try {
                    JSONArray jsonArray = new JSONArray(response);
                    listDataHeader = new ArrayList<>();
                    listHash = new HashMap<>();
                    final int result = jsonArray.length();
                    for (int i = 0; i < result; i++){
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        String surv = jsonObject.getString("survey");
                        String last = jsonObject.getString("last");
                        String next1 = jsonObject.getString("next1");
                        String next2 = jsonObject.getString("next2");
                        String surveyor = jsonObject.getString("surveyor");

                        listDataHeader.add(surv);
                        List<String> data = new ArrayList<>();
                        data.add(last);
                        data.add(next1);
                        data.add(next2);
                        data.add(surveyor);

                        listHash.put(listDataHeader.get(i), data);

                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        })
        {
            @Override
            protected Map<String, String> getParams()throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();

                params.put("noregister", kata);
                return params;
            }
        };
        queue.add(stringRequest);
    }
}```
</div>
</div>
</p>

<p>and this is my adapter</p>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>public class ExpandableListAdapter extends BaseExpandableListAdapter {
    private Context context;
    private List<String> listDataHeader;
    private HashMap<String,List<String>> listHashMap;

    public ExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> listHashMap) {
        this.context = context;
        this.listDataHeader = listDataHeader;
        this.listHashMap = listHashMap;
    }

    @Override
    public int getGroupCount() {
        return listDataHeader.size();
    }

    @Override
    public int getChildrenCount(int i) {
        return listHashMap.get(listDataHeader.get(i)).size();
    }

    @Override
    public Object getGroup(int i) {
        return listDataHeader.get(i);
    }

    @Override
    public Object getChild(int i, int i1) {
        return listHashMap.get(listDataHeader.get(i)).get(i1);
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        String headerTitle = (String)getGroup(i);
        if (view == null){
            LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_group, null);
        }
        TextView lblListHeader = (TextView)view.findViewById(R.id.lblListHeader);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);
        return view;
    }

    @Override
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        final String childText = (String)getChild(i,i1);
        if (view == null){
            LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_item, null);
        }
        TextView txtListChild = (TextView)view.findViewById(R.id.lblListItem);
        txtListChild.setText(childText);
        return view;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }
}</code>```

答:
I didn't go through your full code. I found error in starting onCreate it self.

```<code>   listAdapter = new ExpandableListAdapter(this,listDataHeader,listHash);
   listView.setAdapter(listAdapter);
</code>```

Here listDataHeader and listHash both are null. you remove this line form onCreate and put this line in getData method.

```<code> private void getData(){
    RequestQueue queue = Volley.newRequestQueue(this.getApplicationContext());
    StringRequest stringRequest = new StringRequest(Request.Method.POST, statutory_url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            try {
                JSONArray jsonArray = new JSONArray(response);
                listDataHeader = new ArrayList<>();
                listHash = new HashMap<>();
                final int result = jsonArray.length();
                for (int i = 0; i < result; i++){
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String surv = jsonObject.getString("survey");
                    String last = jsonObject.getString("last");
                    String next1 = jsonObject.getString("next1");
                    String next2 = jsonObject.getString("next2");
                    String surveyor = jsonObject.getString("surveyor");

                    listDataHeader.add(surv);
                    List<String> data = new ArrayList<>();
                    data.add(last);
                    data.add(next1);
                    data.add(next2);
                    data.add(surveyor);

                    listHash.put(listDataHeader.get(i), data);
                    // Adapter code is added here.
                    listAdapter = new ExpandableListAdapter(this,listDataHeader,listHash);
                    listView.setAdapter(listAdapter);
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    })
    {
        @Override
        protected Map<String, String> getParams()throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();

            params.put("noregister", kata);
            return params;
        }
    };
    queue.add(stringRequest);
}
</code>```

try to remove the list adapter from onCreate and put that in getData. Check this code again and rerun this method.

Body:
can anyone help me?
i try to make expandablelistview where the data from server by using POST method. but i got error :
'int java.util.List.size()' on a null object reference
here is my code

private ExpandableListView listView;
    private ExpandableListAdapter listAdapter;
    private List<String> listDataHeader;
    private HashMap<String, List<String>> listHash;
    Button btnSearch;
    EditText search;
    String kata;
    String statutory_url = "http://ds.bki.co.id:7777/ds/android/datasurvey.php";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnSearch = (Button) findViewById(R.id.btnSearch);
        search = (EditText) findViewById(R.id.editText);
        listView = (ExpandableListView) findViewById(R.id.ExpList);

        btnSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                kata = search.getText().toString();
                getData();
            }
        });
        listAdapter = new ExpandableListAdapter(this,listDataHeader,listHash);
        listView.setAdapter(listAdapter);
    }

    private void getData(){
        RequestQueue queue = Volley.newRequestQueue(this.getApplicationContext());
        StringRequest stringRequest = new StringRequest(Request.Method.POST, statutory_url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {

                try {
                    JSONArray jsonArray = new JSONArray(response);
                    listDataHeader = new ArrayList<>();
                    listHash = new HashMap<>();
                    final int result = jsonArray.length();
                    for (int i = 0; i < result; i++){
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        String surv = jsonObject.getString("survey");
                        String last = jsonObject.getString("last");
                        String next1 = jsonObject.getString("next1");
                        String next2 = jsonObject.getString("next2");
                        String surveyor = jsonObject.getString("surveyor");

                        listDataHeader.add(surv);
                        List<String> data = new ArrayList<>();
                        data.add(last);
                        data.add(next1);
                        data.add(next2);
                        data.add(surveyor);

                        listHash.put(listDataHeader.get(i), data);

                    }

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        })
        {
            @Override
            protected Map<String, String> getParams()throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();

                params.put("noregister", kata);
                return params;
            }
        };
        queue.add(stringRequest);
    }
}

and this is my adapter

public class ExpandableListAdapter extends BaseExpandableListAdapter {
    private Context context;
    private List<String> listDataHeader;
    private HashMap<String,List<String>> listHashMap;

    public ExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> listHashMap) {
        this.context = context;
        this.listDataHeader = listDataHeader;
        this.listHashMap = listHashMap;
    }

    @Override
    public int getGroupCount() {
        return listDataHeader.size();
    }

    @Override
    public int getChildrenCount(int i) {
        return listHashMap.get(listDataHeader.get(i)).size();
    }

    @Override
    public Object getGroup(int i) {
        return listDataHeader.get(i);
    }

    @Override
    public Object getChild(int i, int i1) {
        return listHashMap.get(listDataHeader.get(i)).get(i1);
    }

    @Override
    public long getGroupId(int i) {
        return i;
    }

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        String headerTitle = (String)getGroup(i);
        if (view == null){
            LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_group, null);
        }
        TextView lblListHeader = (TextView)view.findViewById(R.id.lblListHeader);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);
        return view;
    }

    @Override
    public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
        final String childText = (String)getChild(i,i1);
        if (view == null){
            LayoutInflater inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_item, null);
        }
        TextView txtListChild = (TextView)view.findViewById(R.id.lblListItem);
        txtListChild.setText(childText);
        return view;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return true;
    }
}

Body:
I didn't go through your full code. I found error in starting onCreate it self.

   listAdapter = new ExpandableListAdapter(this,listDataHeader,listHash);
   listView.setAdapter(listAdapter);

Here listDataHeader and listHash both are null. you remove this line form onCreate and put this line in getData method.

 private void getData(){
    RequestQueue queue = Volley.newRequestQueue(this.getApplicationContext());
    StringRequest stringRequest = new StringRequest(Request.Method.POST, statutory_url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

            try {
                JSONArray jsonArray = new JSONArray(response);
                listDataHeader = new ArrayList<>();
                listHash = new HashMap<>();
                final int result = jsonArray.length();
                for (int i = 0; i < result; i++){
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    String surv = jsonObject.getString("survey");
                    String last = jsonObject.getString("last");
                    String next1 = jsonObject.getString("next1");
                    String next2 = jsonObject.getString("next2");
                    String surveyor = jsonObject.getString("surveyor");

                    listDataHeader.add(surv);
                    List<String> data = new ArrayList<>();
                    data.add(last);
                    data.add(next1);
                    data.add(next2);
                    data.add(surveyor);

                    listHash.put(listDataHeader.get(i), data);
                    // Adapter code is added here.
                    listAdapter = new ExpandableListAdapter(this,listDataHeader,listHash);
                    listView.setAdapter(listAdapter);
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    })
    {
        @Override
        protected Map<String, String> getParams()throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();

            params.put("noregister", kata);
            return params;
        }
    };
    queue.add(stringRequest);
}

try to remove the list adapter from onCreate and put that in getData. Check this code again and rerun this method.


问:
Type mismatch of same type
I'm currently trying to start on a project for one of my CS courses, and I didn't even get five minutes in before I was hit with a rather perplexing error. My code is as follows:

```<code>import java.util.Comparator;
import java.util.List;

public class MergeSorter<T extends Comparable<T>> implements IMergeSorter
{
    private List<T> arrayStore;
    private List<T> temp;
    private int arrSize;

    @Override
    public <T extends Comparable<T>> int sort(List<T> list)
    {
        arrayStore = list;
        return 0;
    }
</code>```

The issue i'm having is with the first line in the sort method,

```<code>arrayStore = list;
</code>```

with Eclipse giving me the following error:

```<code>Type mismatch: cannot convert from List<T extends Comparable<T>> to List<T extends Comparable<T>>
</code>```

Notes:
The method itself was provided to me by my professor, and the only things I have done with this class are add the three variables at the top, change the class' generic type (it was originally (T), which I changed to (T extends Comparable(T)), and add the one line in the "sort" method. Any help is greatly appreciated!

答:
By having the <T extends Comparable<T>> type declaration in the method signature, you're introducing a second type variable T which, although it has the same name, is not the same as the one in your class declaration.

To fix, remove the type declaration from your method signature:

```<code>public int sort(List<T> list)
{
    arrayStore = list;
    return 0;
}
</code>```

Title: Type mismatch of same type

Body:
I'm currently trying to start on a project for one of my CS courses, and I didn't even get five minutes in before I was hit with a rather perplexing error. My code is as follows:

import java.util.Comparator;
import java.util.List;

public class MergeSorter<T extends Comparable<T>> implements IMergeSorter
{
    private List<T> arrayStore;
    private List<T> temp;
    private int arrSize;

    @Override
    public <T extends Comparable<T>> int sort(List<T> list)
    {
        arrayStore = list;
        return 0;
    }

The issue i'm having is with the first line in the sort method,

arrayStore = list;

with Eclipse giving me the following error:

Type mismatch: cannot convert from List<T extends Comparable<T>> to List<T extends Comparable<T>>

Notes:
The method itself was provided to me by my professor, and the only things I have done with this class are add the three variables at the top, change the class' generic type (it was originally (T), which I changed to (T extends Comparable(T)), and add the one line in the "sort" method. Any help is greatly appreciated!

Body:
By having the <T extends Comparable<T>> type declaration in the method signature, you're introducing a second type variable T which, although it has the same name, is not the same as the one in your class declaration.

To fix, remove the type declaration from your method signature:

public int sort(List<T> list)
{
    arrayStore = list;
    return 0;
}


问:
How to call a Action Name on dropdown change in MVC?
How to bind data to second dropdownlist on selecting first dropdownlist ?

I have bind first dropdownlist using strongly typed view.

Now how to call action name and bind second dropdownlist on selection first dropdownlist?

```<code> <tr>
            <td>Select Make:</td>
            <td>@Html.DropDownListFor(m => m.SelectedMake, Model.MakesList, new { @class = "form-control", @onchange = "FillModel()" })</td>
        </tr>
        <tr>
            <td>Select Model</td>
            <td>@Html.DropDownListFor(m => m.SelectedMake, Model.MakesList)</td>
        </tr>
</code>```

Action Name

```<code>public ActionResult FillModel(int MakeId)
        {
            var makedata = objVehicleContext.VehicleMakes.Where(m=>m.MakeId==MakeId);

            ViewBag.makelist = makedata.ToList();
            return View();
        }
</code>```

答:
If I understood your question correct Then you just need to do simple jquery.post

```<code> $("#ddlMake").change(function () {
            $.post("controller/ActionName", function (data) {
                $.each(data, function (val, txt) {
                    $("#ddlModel").append('<option value="' + val + '">' + txt + '</option>');
                });
            });
        });
</code>```

And In controller :

```<code>    public Actionresult GetModel()
    {
        //your dropdown datasource
        return json(ddlModeldatasurce);
    }
</code>```

Body:
How to bind data to second dropdownlist on selecting first dropdownlist ?

I have bind first dropdownlist using strongly typed view.

Now how to call action name and bind second dropdownlist on selection first dropdownlist?

            Select Make:
            @Html.DropDownListFor(m => m.SelectedMake, Model.MakesList, new { @class = "form-control", @onchange = "FillModel()" })

            Select Model
            @Html.DropDownListFor(m => m.SelectedMake, Model.MakesList)

Action Name

public ActionResult FillModel(int MakeId)
        {
            var makedata = objVehicleContext.VehicleMakes.Where(m=>m.MakeId==MakeId);

            ViewBag.makelist = makedata.ToList();
            return View();
        }

Body:
If I understood your question correct Then you just need to do simple jquery.post

 $("#ddlMake").change(function () {
            $.post("controller/ActionName", function (data) {
                $.each(data, function (val, txt) {
                    $("#ddlModel").append('<option value="' + val + '">' + txt + '</option>');
                });
            });
        });

And In controller :

    public Actionresult GetModel()
    {
        //your dropdown datasource
        return json(ddlModeldatasurce);
    }


问:
C/C++ preprocessor single quote?

Possible Duplicate:

  How to single-quote an argument in a macro?

How can it do the following:

```<code>#define MACRO(X) ...
MACRO(a) // should give 'a'
</code>```

答: I might be missing an easier way, but how about #define MACRO(X) ((#X)[0]).  The # stringtizes X and then [0] selects the first character.

Title: C/C++ preprocessor single quote?

Body:
Possible Duplicate:

  How to single-quote an argument in a macro?

How can it do the following:

#define MACRO(X) ...
MACRO(a) // should give 'a'


问:
Check if a row exists, otherwise insert
I need to write a T-SQL stored procedure that updates a row in a table. If the row doesn't exist, insert it. All this steps wrapped by a transaction.

This is for a booking system, so it must be atomic and reliable. It must return true if the transaction was committed and the flight booked.

I'm sure on how to use @@rowcount. This is what I've written until now. Am I on the right road?

```<code>-- BEGIN TRANSACTION (HOW TO DO?)

UPDATE Bookings
 SET TicketsBooked = TicketsBooked + @TicketsToBook
 WHERE FlightId = @Id AND TicketsMax < (TicketsBooked + @TicketsToBook)

-- Here I need to insert only if the row doesn't exists.
-- If the row exists but the condition TicketsMax is violated, I must not insert
-- the row and return FALSE

IF @@ROWCOUNT = 0
BEGIN

 INSERT INTO Bookings ... (omitted)

END

-- END TRANSACTION (HOW TO DO?)

-- Return TRUE (How to do?)
</code>```

答:
```<code>INSERT INTO [DatabaseName1].dbo.[TableName1] SELECT * FROM [DatabaseName2].dbo.[TableName2]
 WHERE [YourPK] not in (select [YourPK] from [DatabaseName1].dbo.[TableName1])
</code>```

OwnerDisplayName: Robert

LastEditorDisplayName: Guffa

ContentLicense: CC BY-SA 4.0

Title: Check if a row exists, otherwise insert

Body:
I need to write a T-SQL stored procedure that updates a row in a table. If the row doesn't exist, insert it. All this steps wrapped by a transaction.

This is for a booking system, so it must be atomic and reliable. It must return true if the transaction was committed and the flight booked.

I'm sure on how to use @@rowcount. This is what I've written until now. Am I on the right road?

-- BEGIN TRANSACTION (HOW TO DO?)

UPDATE Bookings
 SET TicketsBooked = TicketsBooked + @TicketsToBook
 WHERE FlightId = @Id AND TicketsMax < (TicketsBooked + @TicketsToBook)

-- Here I need to insert only if the row doesn't exists.
-- If the row exists but the condition TicketsMax is violated, I must not insert
-- the row and return FALSE

IF @@ROWCOUNT = 0
BEGIN

 INSERT INTO Bookings ... (omitted)

END

-- END TRANSACTION (HOW TO DO?)

-- Return TRUE (How to do?)


问:
HTML to CSS (from inspect element)
I am trying to find the CSS code to place in my wordpress backend to float my page element in the center. I have figured out how to float center, but not how to convert the HTML into CSS.
please help

答:
margin: 0 auto; is correct

However, remember that margin auto won't work on a floated element

See here
http://codepen.io/anon/pen/MpLZVR

```<code>.centered {
  margin: 0 auto;
  padding: 20px;
  background: #e3e3e3;
  max-width: 800px;
}

.breaks-if-floated {
  margin: 0 auto;
  padding: 20px;
  background: #e3e3e3;
  max-width: 800px;
  float: left;
}
</code>```

Title: HTML to CSS (from inspect element)

Body:
margin: 0 auto; is correct

However, remember that margin auto won't work on a floated element

See here
http://codepen.io/anon/pen/MpLZVR

.centered {
  margin: 0 auto;
  padding: 20px;
  background: #e3e3e3;
  max-width: 800px;
}

.breaks-if-floated {
  margin: 0 auto;
  padding: 20px;
  background: #e3e3e3;
  max-width: 800px;
  float: left;
}


问:
Appium's implicitlyWait does not work
I am using Appium to automate an iOS app but met a problem, is there anyone meet the same problem before?

Appium's implicitlyWait API seems to not work. I am using Java and JUnit to run the test, here is the line of code:

driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);

I have checked the debug info in the appium console, it looks correctly:

info: [debug] Set iOS implicit wait to 50000ms

My Environment:

Latest Appium 1.2.1, Java client library 1.6.1, Selenium Java language binding 2.42.2 and sample app 'UICatalog'provided by Sauce Lab.

Thanks in advance for the reply.

答:
The new way of setting  the implicit time out is using the code

```<code>AppiumFieldDecorator decorator = new AppiumFieldDecorator(mobDriver);
decorator.DEFAULT_IMPLICITLY_WAIT_TIMEOUT = longValue;
decorator.DEFAULT_TIMEUNIT = TimeUnit.TimeUnit ;
</code>```

Hope this helps

Title: Appium's implicitlyWait does not work

Body:
The new way of setting  the implicit time out is using the code

AppiumFieldDecorator decorator = new AppiumFieldDecorator(mobDriver);
decorator.DEFAULT_IMPLICITLY_WAIT_TIMEOUT = longValue;
decorator.DEFAULT_TIMEUNIT = TimeUnit.TimeUnit ;

Hope this helps


问:
Add elements to two-dimensionals dynamical table
There is two-dimensional, dynamical allocated table. Put elements inside to table and print them. Code:

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

int main()
{
    int **tab;
    int ROWS=3;
    int COLUMNS=5;
    tab = (int**) malloc(ROWS * sizeof(int*));
    int i=0;
    for(i=0;i<ROWS; ++i)
    {
        tab[i] = (int*)malloc(COLUMNS * sizeof(int));
    }

    i=0;
    int j=0;
    for(;i<ROWS;++i)
    {
        for(;j<COLUMNS;++j)
        {
            tab[i][j]=6;
        }
    }

    i=0; j=0;
    for(;i<ROWS;++i)
    {
        for(;j<COLUMNS;++j)
        {
            printf("%i ", tab[i][j]);
        }
    }

    i=0;
    for(;i<ROWS;++i)
    {
        free(tab[i]);
    }
    free(tab);
}
</code>```

Output Only one row?:

6 6 6 6 6

Output should looks like! (3 rows with 5 columns of 'six'):

6 6 6 6 6

6 6 6 6 6

6 6 6 6 6

答:
Initialize inner loop from zero.</p>

```<code> for(;i<ROWS;++i)
    {
        for(j=0;j<COLUMNS;++j)
        { //^^^ Initialize j = 0
            tab[i][j]=6;
        }
    }

    i=0; j=0;
    for(;i<ROWS;++i)
    {
        for(j=0;j<COLUMNS;++j)
        { //^^^ Initialize j = 0
            printf("%i ", tab[i][j]);
        }
        printf("\n");
    }
</code>```

Body:
There is two-dimensional, dynamical allocated table. Put elements inside to table and print them. Code:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int **tab;
    int ROWS=3;
    int COLUMNS=5;
    tab = (int**) malloc(ROWS * sizeof(int*));
    int i=0;
    for(i=0;i<ROWS; ++i)
    {
        tab[i] = (int*)malloc(COLUMNS * sizeof(int));
    }

    i=0;
    int j=0;
    for(;i<ROWS;++i)
    {
        for(;j<COLUMNS;++j)
        {
            tab[i][j]=6;
        }
    }

    i=0; j=0;
    for(;i<ROWS;++i)
    {
        for(;j<COLUMNS;++j)
        {
            printf("%i ", tab[i][j]);
        }
    }

    i=0;
    for(;i<ROWS;++i)
    {
        free(tab[i]);
    }
    free(tab);
}

Output Only one row?:

6 6 6 6 6

Output should looks like! (3 rows with 5 columns of 'six'):

6 6 6 6 6

6 6 6 6 6

6 6 6 6 6

Body:
Initialize inner loop from zero.

 for(;i<ROWS;++i)
    {
        for(j=0;j<COLUMNS;++j)
        { //^^^ Initialize j = 0
            tab[i][j]=6;
        }
    }

    i=0; j=0;
    for(;i<ROWS;++i)
    {
        for(j=0;j<COLUMNS;++j)
        { //^^^ Initialize j = 0
            printf("%i ", tab[i][j]);
        }
        printf("\n");
    }


问:
req.body for ID is always undefined but my client side is getting the right value by jQuery .click() call
I swear it was working few days ago, so this behavior is really strange for me. Let me show you my code on client side

```<code>$(document).ready(function() {
    $("button").click(function() {
       alert(event.currentTarget.id+"------"+event.currentTarget.value);
       $.post( "/vote", {id:event.currentTarget.id,count:event.currentTarget.value}, $(this).serialize(),
           function(res) {
           }
       );
    })
})
</code>```

As you can see, I tried to passed both id and value back to server once the button clicked. So far everything here is good because I can see the alert pop-up on screen with the correct id number and value (Output example -> aaa------23). Now take a look on my server side code.

```<code>app.post('/vote', function(req, res) {
    var id = req.body.id;
    var count = req.body.count;

    console.log("id: " + id);
    console.log("count: " + count);

    res.sendStatus(200);
    res.end();
});
</code>```

When execute to the line var id = req.body.id, the system returns

TypeError: Cannot read property id of undefined.

count will have the same result.

Is there anything obvious I am missing here? Because I swear it was working before and I haven't touch this part of the code since then. Thanks for the help.

答:
Make sure you use body-parser and it is defined before your route.

```<code>npm install body-parser --save
</code>```

and then include it before you define routes:

```<code>var bodyParser = require('body-parser');
var app = express();

app.use(bodyParser.json());

app.post('/vote', function(req, res) {
   var id = req.body.id;
   var count = req.body.count;

   console.log("id: " + id);
   console.log("count: " + count);

   res.sendStatus(200);
   res.end();
});
</code>```

Body:
I swear it was working few days ago, so this behavior is really strange for me. Let me show you my code on client side

$(document).ready(function() {
    $("button").click(function() {
       alert(event.currentTarget.id+"------"+event.currentTarget.value);
       $.post( "/vote", {id:event.currentTarget.id,count:event.currentTarget.value}, $(this).serialize(),
           function(res) {
           }
       );
    })
})

As you can see, I tried to passed both id and value back to server once the button clicked. So far everything here is good because I can see the alert pop-up on screen with the correct id number and value (Output example -> aaa------23). Now take a look on my server side code.

app.post('/vote', function(req, res) {
    var id = req.body.id;
    var count = req.body.count;

    console.log("id: " + id);
    console.log("count: " + count);

    res.sendStatus(200);
    res.end();
});

When execute to the line var id = req.body.id, the system returns

TypeError: Cannot read property id of undefined.

count will have the same result.

Is there anything obvious I am missing here? Because I swear it was working before and I haven't touch this part of the code since then. Thanks for the help.

Body:
Make sure you use body-parser and it is defined before your route.

npm install body-parser --save

and then include it before you define routes:

var bodyParser = require('body-parser');
var app = express();

app.use(bodyParser.json());

app.post('/vote', function(req, res) {
   var id = req.body.id;
   var count = req.body.count;

   console.log("id: " + id);
   console.log("count: " + count);

   res.sendStatus(200);
   res.end();
});


问:
apps script reocurring out of office message
Trying to get an app script to check the day of week when a message comes in and auto reply with a message if a message is received on certain days, say Saturday and Sunday.  Im looking to format the text in the message somewhat to include color for some text, carriage returns, etc.  I have the below code working with two errors.  1. the reply text is not formatted.  2. I end up with a loop of emails if someone else has an out of office message turned on.  Could this be fixed with adding a label to message threads the auto reply replies to?

Thanks for any help in advance.

```<code>function autoReply() {
  var interval = 5;          //  if the script runs every 5 minutes; change otherwise
  var daysOff = [6,0];   // 1=Mo, 2=Tu, 3=We, 4=Th, 5=Fr, 6=Sa, 0=Su
  var message = "**Auto Reply**  Thank you for your email!   I am out of the office for the weekend spending time with my family. I will be back in the office Monday at 8:00 am.  My usual office hours are Monday- Friday 8:00 am-4:00 pm EST. I monitor email periodically over weekends for emergencies.  I look forward to assisting you.  Thank you!";
  var date = new Date();
  var day = date.getDay();
  if (daysOff.indexOf(day) > -1) {
    var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
    var threads = GmailApp.search('is:inbox after:' + timeFrom);
    for (var i = 0; i < threads.length; i++) {
      threads[i].reply(message);
    }
  }
}
</code>```

答:
First of all, your message does not have any formatting. In essence you are sending a plain text response. Use HTML formatting in the string and use it as the htmlBody parameter (read more on them here).

Next up is the loop of replies. Google has a built in out of office reply system and the way they do it is that someone only gets the auto-reply ever couple of days. I would recommend doing something similar. Once your scrip fires, you store the email by using PropertiesService.getUserProperties() (read more on them here). So basically you would be doing

```<code>PropertiesService.getUserProperties().setProperty(email, date)
</code>```

where you should grab email from the received email message and you already have the date. Keep in mind that you may want to grab all emails involved and inform everyone with the same message, so you will have to loop through them to create a separate entry for each email.

So you want to get the email early on at the beggining of your function and then try PropertiesService.getUserProperties().getProperty(email) and if you manage to retrieve a non null or undefined property, you should quit out of the function with a return because you already sent them a reply and you don't need to anymore.

Body:
Trying to get an app script to check the day of week when a message comes in and auto reply with a message if a message is received on certain days, say Saturday and Sunday.  Im looking to format the text in the message somewhat to include color for some text, carriage returns, etc.  I have the below code working with two errors.  1. the reply text is not formatted.  2. I end up with a loop of emails if someone else has an out of office message turned on.  Could this be fixed with adding a label to message threads the auto reply replies to?

Thanks for any help in advance.

function autoReply() {
  var interval = 5;          //  if the script runs every 5 minutes; change otherwise
  var daysOff = [6,0];   // 1=Mo, 2=Tu, 3=We, 4=Th, 5=Fr, 6=Sa, 0=Su
  var message = "**Auto Reply**  Thank you for your email!   I am out of the office for the weekend spending time with my family. I will be back in the office Monday at 8:00 am.  My usual office hours are Monday- Friday 8:00 am-4:00 pm EST. I monitor email periodically over weekends for emergencies.  I look forward to assisting you.  Thank you!";
  var date = new Date();
  var day = date.getDay();
  if (daysOff.indexOf(day) > -1) {
    var timeFrom = Math.floor(date.valueOf()/1000) - 60 * interval;
    var threads = GmailApp.search('is:inbox after:' + timeFrom);
    for (var i = 0; i < threads.length; i++) {
      threads[i].reply(message);
    }
  }
}

Body:
First of all, your message does not have any formatting. In essence you are sending a plain text response. Use HTML formatting in the string and use it as the htmlBody parameter (read more on them here).

Next up is the loop of replies. Google has a built in out of office reply system and the way they do it is that someone only gets the auto-reply ever couple of days. I would recommend doing something similar. Once your scrip fires, you store the email by using PropertiesService.getUserProperties() (read more on them here). So basically you would be doing

PropertiesService.getUserProperties().setProperty(email, date)

where you should grab email from the received email message and you already have the date. Keep in mind that you may want to grab all emails involved and inform everyone with the same message, so you will have to loop through them to create a separate entry for each email.

So you want to get the email early on at the beggining of your function and then try PropertiesService.getUserProperties().getProperty(email) and if you manage to retrieve a non null or undefined property, you should quit out of the function with a return because you already sent them a reply and you don't need to anymore.


问:
Can't figure out how to print a list in this correct order
Basically I have an arraylist of objects which have a name and startDate and they are in a similar initial order to :

Frank 10/20/1990

Bill 1/2/1990

Frank 2/2/1990

John 9/8/1990

Bill 4/4/1990

Frank 5/1/1990

I'm trying to print them in order of the first names declared and then by date, eg, the final printing should print :

Frank 1/1/1990

Frank 5/1/1990

Frank 10/20/1990

Bill 1/2/1990

Bill 4/4/1990

John 9/8/1990

答:
You should do it in two steps:

First order by name using custom comparator like:

```<code>    Collections.sort(myList, new Comparator<MyObject>() {
       public int compare(MyObject o1, MyObject o2) {
          return o1.getName().compareTo(o2.getName());
       }
    });
</code>```

And store the output in a temp list

Second use temp list to sort by data:

```<code>    Collections.sort(myList, new Comparator<MyObject>() {
       public int compare(MyObject o1, MyObject o2) {
           return o1.getDate().compareTo(o2.getDate());
       }
    });
</code>```

then your list will be sorted as you want.

Body:
You should do it in two steps:

First order by name using custom comparator like:

    Collections.sort(myList, new Comparator<MyObject>() {
       public int compare(MyObject o1, MyObject o2) {
          return o1.getName().compareTo(o2.getName());
       }
    });

And store the output in a temp list

Second use temp list to sort by data:

    Collections.sort(myList, new Comparator<MyObject>() {
       public int compare(MyObject o1, MyObject o2) {
           return o1.getDate().compareTo(o2.getDate());
       }
    });

then your list will be sorted as you want.


问:
Vectorize add-subtract loop in NumPy using O(1) space?
It's easy to vectorize this code with NumPy using extra buffers:

```<code>import numpy.random

def foo(a, b):
    for k in xrange(n):
        bk = b[k]
        b[k] = a[k] - bk
        a[k] += bk

n = 16
x = numpy.random.randn(n)  # some arbitrary input array, this is just for example
y = numpy.random.randn(n)  # some arbitrary input array, this is just for example
foo(x, y)
</code>```

But is there any way for me to make NumPy do so without allocating extra arrays/buffers?

Edit:

I was intending this do this in only 1 vectorized operation (so that each memory location is written to only once), sorry for not mentioning that earlier.

答:
Will this do the trick?

```<code>import numpy.random

def foo(a, b):
    for k in xrange(n):
        a[k], b[k] = (a[k] + b[k], a[k] - b[k])

n = 16
x = numpy.random.randn(n)  # some arbitrary input array, this is just for example
y = numpy.random.randn(n)  # some arbitrary input array, this is just for example
foo(x, y)
</code>```

I don't think it's possible to do what you want in a single vectorized operation because assigning values to multiple variables can't be done at once... But I think cheating with a tuple makes it look like it's possible :]

Body:
It's easy to vectorize this code with NumPy using extra buffers:

import numpy.random

def foo(a, b):
    for k in xrange(n):
        bk = b[k]
        b[k] = a[k] - bk
        a[k] += bk

n = 16
x = numpy.random.randn(n)  # some arbitrary input array, this is just for example
y = numpy.random.randn(n)  # some arbitrary input array, this is just for example
foo(x, y)

But is there any way for me to make NumPy do so without allocating extra arrays/buffers?

Edit:

I was intending this do this in only 1 vectorized operation (so that each memory location is written to only once), sorry for not mentioning that earlier.

Body:
Will this do the trick?

import numpy.random

def foo(a, b):
    for k in xrange(n):
        a[k], b[k] = (a[k] + b[k], a[k] - b[k])

n = 16
x = numpy.random.randn(n)  # some arbitrary input array, this is just for example
y = numpy.random.randn(n)  # some arbitrary input array, this is just for example
foo(x, y)

I don't think it's possible to do what you want in a single vectorized operation because assigning values to multiple variables can't be done at once... But I think cheating with a tuple makes it look like it's possible :]


问:
Pyinstaller Syntax error: 'yield' inside async function (Python 3.5.1)
I am trying to use pyinstaller to create a single executable to distribute to users without Python installed.

The script is a very simple one and just to test waters I'm using just a few lines of code as "Guinea Pig".

The Hello World program - no imports, converts fine.

My Guinea Pig program, which imports matplotlib.pyplot and plots a list of values, fails.

The issue is known and documented here, although they claim it is fixed, or maybe I can't read correctly.
I think the fix should be available in the "dev version" which should be 3.2.1, and I have installed through pip install --upgrade pyinstaller, to no avail.

I keep getting the same syntax error, which occurs when reading the

```<code>module jinja2\asyncsupport.py
</code>```

Any idea how to work around this? My project is ultra simple and it just involves matplotlib, pandas, reading a file and plotting some data.

答:
I got the same error.

The reason is Jinja2 added new async function for Python3.6 in version 2.9.

Please see http://jinja.pocoo.org/docs/2.9/changelog/#version-2-9-6

There are two ways to avoid this error.
Both of these worked for me.

Downgrade jinja2

```<code>   # using Anaconda
   conda install jinja2=2.8.1

   # using pip
   pip install jinja2==2.8.1
</code>```

Install dev version of PyInstaller

```<code>  # install from github
  # Don't run "pip install -U pyinstaller" because the dev version is not released yet
  pip install git+https://github.com/pyinstaller/pyinstaller.git

  # check if "PyInstaller (3.3.dev0+g483dfde)" is in the list
  pip list
</code>```

Body:
I am trying to use pyinstaller to create a single executable to distribute to users without Python installed.

The script is a very simple one and just to test waters I'm using just a few lines of code as "Guinea Pig".

The Hello World program - no imports, converts fine.

My Guinea Pig program, which imports matplotlib.pyplot and plots a list of values, fails.

The issue is known and documented here, although they claim it is fixed, or maybe I can't read correctly.
I think the fix should be available in the "dev version" which should be 3.2.1, and I have installed through pip install --upgrade pyinstaller, to no avail.

I keep getting the same syntax error, which occurs when reading the

module jinja2\asyncsupport.py

Any idea how to work around this? My project is ultra simple and it just involves matplotlib, pandas, reading a file and plotting some data.

Body:
I got the same error.

The reason is Jinja2 added new async function for Python3.6 in version 2.9.

Please see http://jinja.pocoo.org/docs/2.9/changelog/#version-2-9-6

There are two ways to avoid this error.
Both of these worked for me.

Downgrade jinja2

   # using Anaconda
   conda install jinja2=2.8.1

   # using pip
   pip install jinja2==2.8.1

Install dev version of PyInstaller

  # install from github
  # Don't run "pip install -U pyinstaller" because the dev version is not released yet
  pip install git+https://github.com/pyinstaller/pyinstaller.git

  # check if "PyInstaller (3.3.dev0+g483dfde)" is in the list
  pip list


问:
How do I make a looping moviescript finish before stopping it?
I'm animating a leaking object where water drops are falling down. I want the leaking to stop as soon as I click on a different object. When I use stop(); it just stops and the water drops are stuck in the air. Of course I don't want this, how do I fix it?

```<code>Bloempoteetkamer.addEventListener(MouseEvent.CLICK, rotplanteetkamer);

Bloempoteetkamer.buttonMode=true;
Bloempoteetkamer.mouseChildren=false;

function rotplanteetkamer(evt:MouseEvent){
    Planteetkamer.play()
    Druppel.stop()
    Bloempoteetkamer.removeEventListener(MouseEvent.CLICK, rotplanteetkamer);
    Bloempoteetkamer.buttonMode=false;
    stop();
}
</code>```

Bloempoteetkamer is the object that you have to click to stop the leaking.
Druppel is the waterdroplets that are falling down.
Planteetkamer is a different moviescript that plays when I click on Bloempoteetkamer.

答:
You likely want to use EnterFrame option to check, during playback of the MClip (Druppel), if it has actually reached the final frame and only then should the MClip stop().

Try like this :

```<code>Bloempoteetkamer.addEventListener(MouseEvent.CLICK, rotplanteetkamer);

Bloempoteetkamer.buttonMode=true;
Bloempoteetkamer.mouseChildren=false;

function rotplanteetkamer(evt:MouseEvent){
    Planteetkamer.play();
    //Druppel.stop();
    Druppel.addEventListener(Event.ENTER_FRAME, check_if_LastFrame);
    Bloempoteetkamer.removeEventListener(MouseEvent.CLICK, rotplanteetkamer);
    Bloempoteetkamer.buttonMode=false;
    stop();
}

function check_if_LastFrame(target : Event) : void
{
    if (target.currentFrame == target.totalFrames)
    {
        Druppel.stop();
        Druppel.removeEventListener(Event.ENTER_FRAME, check_ifLastFrame);
    }
}
</code>```

Body:
I'm animating a leaking object where water drops are falling down. I want the leaking to stop as soon as I click on a different object. When I use stop(); it just stops and the water drops are stuck in the air. Of course I don't want this, how do I fix it?

Bloempoteetkamer.addEventListener(MouseEvent.CLICK, rotplanteetkamer);

Bloempoteetkamer.buttonMode=true;
Bloempoteetkamer.mouseChildren=false;

function rotplanteetkamer(evt:MouseEvent){
    Planteetkamer.play()
    Druppel.stop()
    Bloempoteetkamer.removeEventListener(MouseEvent.CLICK, rotplanteetkamer);
    Bloempoteetkamer.buttonMode=false;
    stop();
}

Bloempoteetkamer is the object that you have to click to stop the leaking.
Druppel is the waterdroplets that are falling down.
Planteetkamer is a different moviescript that plays when I click on Bloempoteetkamer.

Body:
You likely want to use EnterFrame option to check, during playback of the MClip (Druppel), if it has actually reached the final frame and only then should the MClip stop().

Try like this :

Bloempoteetkamer.addEventListener(MouseEvent.CLICK, rotplanteetkamer);

Bloempoteetkamer.buttonMode=true;
Bloempoteetkamer.mouseChildren=false;

function rotplanteetkamer(evt:MouseEvent){
    Planteetkamer.play();
    //Druppel.stop();
    Druppel.addEventListener(Event.ENTER_FRAME, check_if_LastFrame);
    Bloempoteetkamer.removeEventListener(MouseEvent.CLICK, rotplanteetkamer);
    Bloempoteetkamer.buttonMode=false;
    stop();
}

function check_if_LastFrame(target : Event) : void
{
    if (target.currentFrame == target.totalFrames)
    {
        Druppel.stop();
        Druppel.removeEventListener(Event.ENTER_FRAME, check_ifLastFrame);
    }
}


答:
Seems it can't be done with the C preprocessor, at least the gcc docs states it bluntly:

There is no way to convert a macro
  argument into a character constant.

Title: C/C++ preprocessor single quote?

Body:
Possible Duplicate:

  How to single-quote an argument in a macro?

How can it do the following:

#define MACRO(X) ...
MACRO(a) // should give 'a'


问:
C# Avoiding Duplicated Logic
Suppose I had a base class A, with subclasses B, C and D. I have a class, MyClass which contains an overload for each of them. I want a counter to increment any time one of these methods is invoked from anywhere other than inside MyClass. This can be accomplished with a few simple helper methods:

```<code>public class MyClass
{
   int counter;

   public doSomethingExternal(B b) {counter++; doSomething(b);}
   public doSomethingExternal(C c) {counter++; doSomething(c);}
   public doSomethingExternal(D d) {counter++; doSomething(d);}

   private doSomething(B b) {...}
   private doSomething(C c) {...}
   private doSomething(D d) {...}
}
</code>```

This really bothers the dev in me. Is there no way better way we can write those helper methods so that we don't have duplicated logic for every subclass? The solution I envision is something like:

```<code>// Magically, we know which type we are and call the correct doSomething
public doSomethingExternal(A a) {counter++; doSomething(a);}
</code>```

I think this kind of generalization could be accomplished with Reflection, but I have heard that reflection is generally slow and can be complicated to understand. I am curious if there is a more conventional pattern I am overlooking that solves this logic-duplication issue.

答:
Well one way you can solve this is to make the classes A, B and C implement an interface. Depending on what the doSomething function is doing you can do something like this.

```<code>public interface IFoo
{
   void DoSomething();
}
</code>```

then you can have one public function in MyClass.

```<code>public void doSomethingExternal(IFoo foo)
{
   counter++;
   foo.DoSomething();
}
</code>```

Title: C# Avoiding Duplicated Logic

Body:
Suppose I had a base class A, with subclasses B, C and D. I have a class, MyClass which contains an overload for each of them. I want a counter to increment any time one of these methods is invoked from anywhere other than inside MyClass. This can be accomplished with a few simple helper methods:

public class MyClass
{
   int counter;

   public doSomethingExternal(B b) {counter++; doSomething(b);}
   public doSomethingExternal(C c) {counter++; doSomething(c);}
   public doSomethingExternal(D d) {counter++; doSomething(d);}

   private doSomething(B b) {...}
   private doSomething(C c) {...}
   private doSomething(D d) {...}
}

This really bothers the dev in me. Is there no way better way we can write those helper methods so that we don't have duplicated logic for every subclass? The solution I envision is something like:

// Magically, we know which type we are and call the correct doSomething
public doSomethingExternal(A a) {counter++; doSomething(a);}

I think this kind of generalization could be accomplished with Reflection, but I have heard that reflection is generally slow and can be complicated to understand. I am curious if there is a more conventional pattern I am overlooking that solves this logic-duplication issue.

Body:
Well one way you can solve this is to make the classes A, B and C implement an interface. Depending on what the doSomething function is doing you can do something like this.

public interface IFoo
{
   void DoSomething();
}

then you can have one public function in MyClass.

public void doSomethingExternal(IFoo foo)
{
   counter++;
   foo.DoSomething();
}