问:
WPF - Databinding Color to plain simple Window or Canvas in a Window Background - No controls
I need an answer so i can explore. I am running into a brick wall here:

I would like to use:

```<code>        for (int c = 0; c < 255; c++)
        {

            Color = Color.FromArgb(255, (byte)c, (byte)(255 - c), (byte)c);
            Thread.Sleep(3);
        }
</code>```

Each time the "Color" is recomputed, i would like the Window or the Canvas in the Window to IMMEDIATELY change color...so i get to SEE the cool color changes. Why is this so hard? I need to see this, but i'm hitting a brick wall. I copied a Type Converter here:

```<code>[ValueConversion(typeof(Color),typeof(SolidColorBrush))]
public class ColorBrushConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Color color = (Color)value;
        return new SolidColorBrush(color);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

}
</code>```

THANK YOU FOR ANY HELP!

答:
A simple example of how you can bind a Color Property from code behind to a Canvas Background. Things to note

Implement INotifyPropertyChanged. The Background for the Canvas will get updated upon OnPropertyChanged which will execute everytime MyColorProperty changes.

Setting the DataContext = this; in the constructor will make all Controls in Window inherit this DataContext (unless this is overriden).

xaml

```<code><Canvas ...>
    <Canvas.Background>
        <SolidColorBrush Color="{Binding MyColorProperty}"/>
    </Canvas.Background>
</code>```

Code behind

```<code>public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    // ...

    private Color m_myColorProperty;
    public Color MyColorProperty
    {
        get
        {
            return m_myColorProperty;
        }
        set
        {
            m_myColorProperty = value;
            OnPropertyChanged("MyColorProperty");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private void SwitchBackground()
    {
        if (MyColorProperty == Colors.Red)
        {
            MyColorProperty = Colors.Black;
        }
        else
        {
            MyColorProperty = Colors.Red;
        }
    }
}
</code>```

Update

To run the Background animation you can use a BackgroundWorker like this

```<code>private BackgroundWorker m_changeColorBgWorker = null;

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    m_changeColorBgWorker = new BackgroundWorker();
    m_changeColorBgWorker.DoWork += new DoWorkEventHandler(m_changeColorBgWorker_DoWork);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
    if (m_changeColorBgWorker.IsBusy == false)
    {
        m_changeColorBgWorker.RunWorkerAsync();
    }
}
void m_changeColorBgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        for (int c = 0; c < 254; c++)
        {
            MyColorProperty = Color.FromArgb(255, (byte)c, (byte)(255 - c), (byte)c);
            Thread.Sleep(10);
        }
    }
}
</code>```

You can set the MyColorProperty directly in the thread because changes fired by INotifyPropertyChanged are automatically marshalled back onto the dispatcher. This does not go for INotifyCollectionChanged however, just so you know.

Body:
I need an answer so i can explore. I am running into a brick wall here:

I would like to use:

        for (int c = 0; c < 255; c++)
        {

            Color = Color.FromArgb(255, (byte)c, (byte)(255 - c), (byte)c);
            Thread.Sleep(3);
        }

Each time the "Color" is recomputed, i would like the Window or the Canvas in the Window to IMMEDIATELY change color...so i get to SEE the cool color changes. Why is this so hard? I need to see this, but i'm hitting a brick wall. I copied a Type Converter here:

[ValueConversion(typeof(Color),typeof(SolidColorBrush))]
public class ColorBrushConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Color color = (Color)value;
        return new SolidColorBrush(color);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

}

THANK YOU FOR ANY HELP!

Body:
A simple example of how you can bind a Color Property from code behind to a Canvas Background. Things to note

Implement INotifyPropertyChanged. The Background for the Canvas will get updated upon OnPropertyChanged which will execute everytime MyColorProperty changes.

Setting the DataContext = this; in the constructor will make all Controls in Window inherit this DataContext (unless this is overriden).

xaml

<Canvas ...>
    <Canvas.Background>
        <SolidColorBrush Color="{Binding MyColorProperty}"/>
    </Canvas.Background>

Code behind

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    // ...

    private Color m_myColorProperty;
    public Color MyColorProperty
    {
        get
        {
            return m_myColorProperty;
        }
        set
        {
            m_myColorProperty = value;
            OnPropertyChanged("MyColorProperty");
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private void SwitchBackground()
    {
        if (MyColorProperty == Colors.Red)
        {
            MyColorProperty = Colors.Black;
        }
        else
        {
            MyColorProperty = Colors.Red;
        }
    }
}

Update

To run the Background animation you can use a BackgroundWorker like this

private BackgroundWorker m_changeColorBgWorker = null;

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    m_changeColorBgWorker = new BackgroundWorker();
    m_changeColorBgWorker.DoWork += new DoWorkEventHandler(m_changeColorBgWorker_DoWork);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
    if (m_changeColorBgWorker.IsBusy == false)
    {
        m_changeColorBgWorker.RunWorkerAsync();
    }
}
void m_changeColorBgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    while (true)
    {
        for (int c = 0; c < 254; c++)
        {
            MyColorProperty = Color.FromArgb(255, (byte)c, (byte)(255 - c), (byte)c);
            Thread.Sleep(10);
        }
    }
}

You can set the MyColorProperty directly in the thread because changes fired by INotifyPropertyChanged are automatically marshalled back onto the dispatcher. This does not go for INotifyCollectionChanged however, just so you know.


来源: stackexchange

问:
create n item long playlist-like list from multiple other lists
I'm trying to create a list with values out of three other lists (high, medium and low). The new list should evaluate from the probability_array from which list it should pick a random value. The new list should be playlist-like: before a randomly chosen value will be picked twice (from high, medium or low), all other values of the specific list (high, medium or low) must be in the newly generated list.

Any ideas, how I can achieve this. My code so far:

```<code>import numpy as np

array_length = 30

high = [(1, 2), 3, 4, 5, 6, (7, 8, 9)]
medium = [10, 11, (12, 13), 14]
low = [100, 101, 102, (103, 104)]

probability_array = np.random.choice(
    ['High', 'Medium', 'Low',],
    array_length,
    p=[4/7, 2/7, 1/7]
)
# i. e.
"""
['Low' 'High' 'High' 'High' 'High' 'High' 'Medium' 'Medium' 'High' 'Medium'
 'High' 'High' 'Medium' 'Medium' 'High' 'High' 'Medium' 'Medium' 'High'
 'High' 'High' 'High' 'High' 'Medium' 'Medium' 'High' 'High' 'High' 'Low'
 'High']
"""

# new list should look like:
"""
[102, (1, 2), 4, (7, 8, 9), 3, 6, 14, ...]
"""
</code>```

Thanks

答:
with np.random.choice there is an option to specify the probability of items being chosen. You can build a list of high, medium, low with that and feed it into another loop to construct your playlist correctly

- at roganjosh's suggestion, I also removed the ability for the same item to occur back to back

```<code>import numpy as np
import random
import collections

playlist_length = 30

# key is the match strength (ie. high, medium, low)
matches = {
    'high' : {
        'items' : [(1, 2), 3, 4, 5, 6, (7, 8, 9)],
        'prob' : 4/7
    },
    'medium' : {
        'items' : [10, 11, (12, 13), 14],
        'prob' : 2/7
    },
    'low' : {
        'items' : [100, 101, 102, (103, 104)],
        'prob' : 1/7
    }
}

# create two lists:
# a is a list of match strengths
# p is the desired probability of an item from that match strength occuring
a, p = zip(*[(match, matches[match]['prob']) for match in matches])

# build a list of match strengths, with our chosen size and probability
results = np.random.choice(a=a, p=p, size=playlist_length)

# build our playlist
playlist = []
last_item = None
for match_strength in results:
    # count all the items currently in playlist (a bit inefficient, probably don't have to recreate the Counter obj everytime)
    count_playlist = collections.Counter(playlist)

    # filter items of the given match strength, leaving out those that are at the current max
    items = matches[match_strength]['items']
    max_count = max([count_playlist[item] for item in items])
    filtered = list(filter(lambda item: count_playlist[item] < max_count, items))

    # if all items have the same count, reset the filtered list to be any item
    if not len(filtered):
        filtered = items

    # drop last item so that it does not repeat
    if last_item and last_item in filtered and len(filtered) > 1:
        filtered.remove(last_item)

    # add one from filtered items to playlist
    new_item = random.choice(filtered)
    playlist.append(new_item)
    last_item = new_item

print(collections.Counter(results))
print(playlist)
</code>```

output:

the counter shows that the different match strength occur at acceptable frequencies Counter({'high': 19, 'medium': 10, 'low': 1})

and the playlist was

[(1, 2), 14, 4, 5, 102, 3, (7, 8, 9), 6, (1, 2), 11, 10, (12, 13), 4, 3, 10, (12, 13), 5, 11, (7, 8, 9), 14, 6, 4, (7, 8, 9), 5, 10, (1, 2), 6, 3, 11, 4]

ContentLicense: CC BY-SA 3.0

Body:
I'm trying to create a list with values out of three other lists (high, medium and low). The new list should evaluate from the probability_array from which list it should pick a random value. The new list should be playlist-like: before a randomly chosen value will be picked twice (from high, medium or low), all other values of the specific list (high, medium or low) must be in the newly generated list.

Any ideas, how I can achieve this. My code so far:

import numpy as np

array_length = 30

high = [(1, 2), 3, 4, 5, 6, (7, 8, 9)]
medium = [10, 11, (12, 13), 14]
low = [100, 101, 102, (103, 104)]

probability_array = np.random.choice(
    ['High', 'Medium', 'Low',],
    array_length,
    p=[4/7, 2/7, 1/7]
)
# i. e.
"""
['Low' 'High' 'High' 'High' 'High' 'High' 'Medium' 'Medium' 'High' 'Medium'
 'High' 'High' 'Medium' 'Medium' 'High' 'High' 'Medium' 'Medium' 'High'
 'High' 'High' 'High' 'High' 'Medium' 'Medium' 'High' 'High' 'High' 'Low'
 'High']
"""

# new list should look like:
"""
[102, (1, 2), 4, (7, 8, 9), 3, 6, 14, ...]
"""

Thanks

Body:
with np.random.choice there is an option to specify the probability of items being chosen. You can build a list of high, medium, low with that and feed it into another loop to construct your playlist correctly

- at roganjosh's suggestion, I also removed the ability for the same item to occur back to back

import numpy as np
import random
import collections

playlist_length = 30

# key is the match strength (ie. high, medium, low)
matches = {
    'high' : {
        'items' : [(1, 2), 3, 4, 5, 6, (7, 8, 9)],
        'prob' : 4/7
    },
    'medium' : {
        'items' : [10, 11, (12, 13), 14],
        'prob' : 2/7
    },
    'low' : {
        'items' : [100, 101, 102, (103, 104)],
        'prob' : 1/7
    }
}

# create two lists:
# a is a list of match strengths
# p is the desired probability of an item from that match strength occuring
a, p = zip(*[(match, matches[match]['prob']) for match in matches])

# build a list of match strengths, with our chosen size and probability
results = np.random.choice(a=a, p=p, size=playlist_length)

# build our playlist
playlist = []
last_item = None
for match_strength in results:
    # count all the items currently in playlist (a bit inefficient, probably don't have to recreate the Counter obj everytime)
    count_playlist = collections.Counter(playlist)

    # filter items of the given match strength, leaving out those that are at the current max
    items = matches[match_strength]['items']
    max_count = max([count_playlist[item] for item in items])
    filtered = list(filter(lambda item: count_playlist[item] < max_count, items))

    # if all items have the same count, reset the filtered list to be any item
    if not len(filtered):
        filtered = items

    # drop last item so that it does not repeat
    if last_item and last_item in filtered and len(filtered) > 1:
        filtered.remove(last_item)

    # add one from filtered items to playlist
    new_item = random.choice(filtered)
    playlist.append(new_item)
    last_item = new_item

print(collections.Counter(results))
print(playlist)

output:

the counter shows that the different match strength occur at acceptable frequencies Counter({'high': 19, 'medium': 10, 'low': 1})

and the playlist was

[(1, 2), 14, 4, 5, 102, 3, (7, 8, 9), 6, (1, 2), 11, 10, (12, 13), 4, 3, 10, (12, 13), 5, 11, (7, 8, 9), 14, 6, 4, (7, 8, 9), 5, 10, (1, 2), 6, 3, 11, 4]


问:
Meteor Collection naming convention
I have inherited a naming convention form a tutorial but am not sure that it is the best:

```<code>Posts = new Meteor.Collection("posts", {.......
</code>```

Note the case on the naming, now this gets quite confusing when working between code/the mongo console/minimongo console - are there any reasons not to use the same name:

```<code>Posts = new Meteor.Collection("Posts", {.......
</code>```

答:
The Meteor recommendation meteor docs is to use:

CamelCaseCollectionName = new Mongo.Collection('lowercasecollectionname')

```<code>    Posts = new Mongo.Collection('posts', {...});
</code>```

In this way, there is no confusion, when you received a message, with lowercase is a mongo side, if is an uppercase will be Meteor Collection's side.

As well, keep names in plural  ;-)

Title: Meteor Collection naming convention

Body:
I have inherited a naming convention form a tutorial but am not sure that it is the best:

Posts = new Meteor.Collection("posts", {.......

Note the case on the naming, now this gets quite confusing when working between code/the mongo console/minimongo console - are there any reasons not to use the same name:

Posts = new Meteor.Collection("Posts", {.......

Body:
The Meteor recommendation meteor docs is to use:

CamelCaseCollectionName = new Mongo.Collection('lowercasecollectionname')

    Posts = new Mongo.Collection('posts', {...});

In this way, there is no confusion, when you received a message, with lowercase is a mongo side, if is an uppercase will be Meteor Collection's side.

As well, keep names in plural  ;-)


问:
C# append object to xml file using serialization
I am trying append a serialized object to an existing xml file beneath the root element, which I thought would be simple but is proving to be a little challenging.

The problem is in the AddShortcut method but I added some more code for completeness.

I believe what I need to do is:

load the file into an XmlDocument.

navigate to the node I want to append beneath (here the node name is Shortcuts).

create some type of writer and then serialize the object.

save the XmlDocument.

The trouble is in steps 2 and 3. I have tried different variations but I think using XPathNavigator somehow to find the "root" node to append under is a step in the right direction.

I have also looked at almost every question on Stack Overflow on the subject.

Any suggestions welcome. Here is my code

```<code>class XmlEngine
{
   public string FullPath { get; set; } // the full path to the xmlDocument
   private readonly XmlDocument xDoc;

   public XmlEngine(string fullPath, string startElement, string[] rElements)
   {
      FullPath = fullPath;
      xDoc = new XmlDocument();
      CreateXmlFile(FullPath, startElement, rElements);
   }

   public void CreateXmlFile(string path, string startElement, string[] rElements)
   {
     try
     {
       if (!File.Exists(path))
       {
         // create a txt writer
         XmlTextWriter wtr = new XmlTextWriter(path, System.Text.Encoding.UTF8);

         // make sure the file is well formatted
         wtr.Formatting = Formatting.Indented;

         wtr.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
         wtr.WriteStartElement(startElement);
         wtr.Close();

         // write the top level root elements
         writeRootElements(path, rElements);
       }
     }
     catch (Exception ex)
     {
       Console.WriteLine("Error: " + ex.Message);
       Console.WriteLine("Could not create file: " + path);
     }
  }

  public void AddShortcut(Shortcut s)
  {
     xDoc.Load(FullPath);
     rootNode = xDoc.AppendChild(xDoc.CreateElement("Shortcuts"));

     var serializer = new XmlSerializer(s.GetType());

     using (var writer = new StreamWriter(FullPath, true))
     {
        XmlWriterSettings ws = new XmlWriterSettings();
        ws.OmitXmlDeclaration = true;

        serializer.Serialize(writer, s);
     }

     xDoc.Save(FullPath);

  }

}
</code>```

答:
load the file into an XmlDocument.

navigate to the node I want to append beneath (here the node name is Shortcuts).

create some type of writer and then serialize the object.

save the XmlDocument

So:

```<code>public void AddShortcut(Shortcut s)
{
    // 1. load existing xml
    xDoc.Load(FullPath);
    // 2. create an XML node from object
    XmlElement node = SerializeToXmlElement(s);
    // 3. append that node to Shortcuts node under XML root
    var shortcutsNode = xDoc.CreateElement("Shortcuts")
    shortcutsNode.AppendChild(node);
    xDoc.DocumentElement.AppendChild(shortcutsNode);
    // 4. save changes
    xDoc.Save(FullPath);
}

public static XmlElement SerializeToXmlElement(object o)
{
    XmlDocument doc = new XmlDocument();
    using(XmlWriter writer = doc.CreateNavigator().AppendChild())
    {
        new XmlSerializer(o.GetType()).Serialize(writer, o);
    }
    return doc.DocumentElement;
}
</code>```

This post

Body:
I am trying append a serialized object to an existing xml file beneath the root element, which I thought would be simple but is proving to be a little challenging.

The problem is in the AddShortcut method but I added some more code for completeness.

I believe what I need to do is:

load the file into an XmlDocument.

navigate to the node I want to append beneath (here the node name is Shortcuts).

create some type of writer and then serialize the object.

save the XmlDocument.

The trouble is in steps 2 and 3. I have tried different variations but I think using XPathNavigator somehow to find the "root" node to append under is a step in the right direction.

I have also looked at almost every question on Stack Overflow on the subject.

Any suggestions welcome. Here is my code

class XmlEngine
{
   public string FullPath { get; set; } // the full path to the xmlDocument
   private readonly XmlDocument xDoc;

   public XmlEngine(string fullPath, string startElement, string[] rElements)
   {
      FullPath = fullPath;
      xDoc = new XmlDocument();
      CreateXmlFile(FullPath, startElement, rElements);
   }

   public void CreateXmlFile(string path, string startElement, string[] rElements)
   {
     try
     {
       if (!File.Exists(path))
       {
         // create a txt writer
         XmlTextWriter wtr = new XmlTextWriter(path, System.Text.Encoding.UTF8);

         // make sure the file is well formatted
         wtr.Formatting = Formatting.Indented;

         wtr.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
         wtr.WriteStartElement(startElement);
         wtr.Close();

         // write the top level root elements
         writeRootElements(path, rElements);
       }
     }
     catch (Exception ex)
     {
       Console.WriteLine("Error: " + ex.Message);
       Console.WriteLine("Could not create file: " + path);
     }
  }

  public void AddShortcut(Shortcut s)
  {
     xDoc.Load(FullPath);
     rootNode = xDoc.AppendChild(xDoc.CreateElement("Shortcuts"));

     var serializer = new XmlSerializer(s.GetType());

     using (var writer = new StreamWriter(FullPath, true))
     {
        XmlWriterSettings ws = new XmlWriterSettings();
        ws.OmitXmlDeclaration = true;

        serializer.Serialize(writer, s);
     }

     xDoc.Save(FullPath);

  }

}

Body:
load the file into an XmlDocument.

navigate to the node I want to append beneath (here the node name is Shortcuts).

create some type of writer and then serialize the object.

save the XmlDocument

So:

public void AddShortcut(Shortcut s)
{
    // 1. load existing xml
    xDoc.Load(FullPath);
    // 2. create an XML node from object
    XmlElement node = SerializeToXmlElement(s);
    // 3. append that node to Shortcuts node under XML root
    var shortcutsNode = xDoc.CreateElement("Shortcuts")
    shortcutsNode.AppendChild(node);
    xDoc.DocumentElement.AppendChild(shortcutsNode);
    // 4. save changes
    xDoc.Save(FullPath);
}

public static XmlElement SerializeToXmlElement(object o)
{
    XmlDocument doc = new XmlDocument();
    using(XmlWriter writer = doc.CreateNavigator().AppendChild())
    {
        new XmlSerializer(o.GetType()).Serialize(writer, o);
    }
    return doc.DocumentElement;
}

This post


问:
Figure out group of tasks completion time using TaskQueue and Datastore
I have a push task queue and each of my jobs consists of multiple similar TaskQueue tasks. Each of these tasks takes less than a second to finish and can add new tasks to the queue (they should be also completed to consider the job finished). Task results are written to a DataStore.

The goal is to understand when a job has finished, i.e. all of its tasks are completed.

Writes are really frequent and I can't store the results inside one entity group. Is there a good workaround for this?

答:
In a similar context I used a scheme based on memcache, which doesn't have a significant write rate limitation as datastore entity groups:

each job gets a unique memcache key associated with it, which it passes to each of subsequent execution tasks it may enqueue

every execution task updates the memcache value corresponding to the job key with the current timestamp and also enqueues a completion check task, delayed with an idle timeout value, large enough to declare the job completed if elapsed.

every completion check task compares the memcache value corresponding to the job key against the current timestamp:

if the delta is less than the idle timeout it means the job is not complete (some other task was executed since this completion check task was enqueued, hence some other completion check task is in the queue)

otherwise the job is completed

Note: the idle timeout should be larger than the maximum time a task might spend in the queue.


问:
Error while calling sqlite database query
I get the following exception when running from code. Which argument is the message talking about?

```<code>Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range.  The statement has 0 parameters.
at android.database.sqlite.SQLiteProgram.bind(SQLiteProgram.java:212)
at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:166)
at android.database.sqlite.SQLiteProgram.bindAllArgsAsStrings(SQLiteProgram.java:200)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1284)
at su.joel.punchintime.ShowRawDB.displayDatabaseInfo(ShowRawDB.java:53)
at su.joel.punchintime.ShowRawDB.onCreate(ShowRawDB.java:19)
</code>```

at this line: Cursor cursor = db.rawQuery(queryString, whereArgs);

The activity:

```<code>package su.joel.punchintime;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class ShowRawDB extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_raw_db);
        displayDatabaseInfo();
    }
    private void displayDatabaseInfo() {
        DatabaseHelper DBHelper = new DatabaseHelper(this);
        SQLiteDatabase db = DBHelper.getReadableDatabase();
        String[] projection = {
                DBHelper.COL_ID,
                DBHelper.COL_DATE,
                DBHelper.COL_PUNCHIN
        };
        String selection = "null";
        String[] selectionArgs = { "null" };
        String sortOrder =
                DBHelper.COL_DATE + " DESC";
        String queryString =
                "SELECT * FROM punchlog";
        String[] whereArgs = new String[] {""};
        Cursor cursor = db.rawQuery(queryString, whereArgs);
        List itemIds = new ArrayList<>();
        while(cursor.moveToNext()) {
            long itemId = cursor.getLong(
                    cursor.getColumnIndexOrThrow(DBHelper.COL_ID));
            itemIds.add(itemId);
        }
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.activity_listview, itemIds);
        ListView lst = (ListView) findViewById(R.id.listDB);
        lst.setAdapter(adapter);
        cursor.close();
    }
}
</code>```

And the database helper:

```<code>package su.joel.punchintime;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public final class DatabaseHelper extends SQLiteOpenHelper {
        public static final String TABLE_NAME = "punchlog";
        public static final String COL_ID = "_id";
        public static final String COL_DATE = "date";
        public static final String COL_PUNCHIN = "punchin";
        public static final String COL_PUNCHOUT = "punchout";
        public static final String COL_ONDUTY = "onduty";
        public static final String COL_FORGOTIN = "forgotin";
        public static final String COL_FORGOTOUT = "forgotout";
        public static final String COL_LATEIN = "latein";
        public static final String COL_LATEOUT = "lateout";
    String SQL_CREATE_ENTRIES =
            "CREATE TABLE " + TABLE_NAME + " (" +
                    COL_ID + " INTEGER PRIMARY KEY," +
                    COL_DATE + " TEXT," +
                    COL_PUNCHIN + " TEXT," +
                    COL_PUNCHOUT + " TEXT," +
                    COL_ONDUTY + " INTEGER," +
                    COL_FORGOTIN + " INTEGER," +
                    COL_FORGOTOUT + " INTEGER," +
                    COL_LATEIN + " INTEGER," +
                    COL_LATEOUT + " INTEGER);";
    String SQL_DELETE_ENTRIES =
            "DROP TABLE IF EXISTS " + TABLE_NAME;
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "PunchInTime.db";
    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(SQL_DELETE_ENTRIES);
        System.out.println(SQL_CREATE_ENTRIES);
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}
</code>```

答:
```<code>Cursor cursor = db.rawQuery(queryString, whereArgs);
</code>```

Instead of the above code, replace with

```<code>Cursor cursor = db.rawQuery(queryString, null);
</code>```

This is because your whereArgs is empty.

Body:
I get the following exception when running from code. Which argument is the message talking about?

Caused by: java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range.  The statement has 0 parameters.
at android.database.sqlite.SQLiteProgram.bind(SQLiteProgram.java:212)
at android.database.sqlite.SQLiteProgram.bindString(SQLiteProgram.java:166)
at android.database.sqlite.SQLiteProgram.bindAllArgsAsStrings(SQLiteProgram.java:200)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:47)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1284)
at su.joel.punchintime.ShowRawDB.displayDatabaseInfo(ShowRawDB.java:53)
at su.joel.punchintime.ShowRawDB.onCreate(ShowRawDB.java:19)

at this line: Cursor cursor = db.rawQuery(queryString, whereArgs);

The activity:

package su.joel.punchintime;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class ShowRawDB extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_raw_db);
        displayDatabaseInfo();
    }
    private void displayDatabaseInfo() {
        DatabaseHelper DBHelper = new DatabaseHelper(this);
        SQLiteDatabase db = DBHelper.getReadableDatabase();
        String[] projection = {
                DBHelper.COL_ID,
                DBHelper.COL_DATE,
                DBHelper.COL_PUNCHIN
        };
        String selection = "null";
        String[] selectionArgs = { "null" };
        String sortOrder =
                DBHelper.COL_DATE + " DESC";
        String queryString =
                "SELECT * FROM punchlog";
        String[] whereArgs = new String[] {""};
        Cursor cursor = db.rawQuery(queryString, whereArgs);
        List itemIds = new ArrayList<>();
        while(cursor.moveToNext()) {
            long itemId = cursor.getLong(
                    cursor.getColumnIndexOrThrow(DBHelper.COL_ID));
            itemIds.add(itemId);
        }
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.activity_listview, itemIds);
        ListView lst = (ListView) findViewById(R.id.listDB);
        lst.setAdapter(adapter);
        cursor.close();
    }
}

And the database helper:

package su.joel.punchintime;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public final class DatabaseHelper extends SQLiteOpenHelper {
        public static final String TABLE_NAME = "punchlog";
        public static final String COL_ID = "_id";
        public static final String COL_DATE = "date";
        public static final String COL_PUNCHIN = "punchin";
        public static final String COL_PUNCHOUT = "punchout";
        public static final String COL_ONDUTY = "onduty";
        public static final String COL_FORGOTIN = "forgotin";
        public static final String COL_FORGOTOUT = "forgotout";
        public static final String COL_LATEIN = "latein";
        public static final String COL_LATEOUT = "lateout";
    String SQL_CREATE_ENTRIES =
            "CREATE TABLE " + TABLE_NAME + " (" +
                    COL_ID + " INTEGER PRIMARY KEY," +
                    COL_DATE + " TEXT," +
                    COL_PUNCHIN + " TEXT," +
                    COL_PUNCHOUT + " TEXT," +
                    COL_ONDUTY + " INTEGER," +
                    COL_FORGOTIN + " INTEGER," +
                    COL_FORGOTOUT + " INTEGER," +
                    COL_LATEIN + " INTEGER," +
                    COL_LATEOUT + " INTEGER);";
    String SQL_DELETE_ENTRIES =
            "DROP TABLE IF EXISTS " + TABLE_NAME;
    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "PunchInTime.db";
    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(SQL_DELETE_ENTRIES);
        System.out.println(SQL_CREATE_ENTRIES);
        onCreate(db);
    }
    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onUpgrade(db, oldVersion, newVersion);
    }
}

Body:
Cursor cursor = db.rawQuery(queryString, whereArgs);

Instead of the above code, replace with

Cursor cursor = db.rawQuery(queryString, null);

This is because your whereArgs is empty.


问:
Selenium: Trigger mousewheel on an IWebElement with C#
Description: A complex structure of HTML elements (rectangles) displayed on the screen, no overlaps, each rectangle having a distinct HTML id attribute (hence pickable by Selenium IWebDriver and C# code).

Target: I need programatically with Selenium and C# to create and trigger mousewheel event (via IJavaScriptExecutor or some other methods) on a selected rectangle element.

Q: How this can be done? Thank you

答:
This is my implementation after investigating </p>

```<code>//wheelTicks: negative for zoomin, positive to zoomout
public object zoomElementById(string elemId, int wheelTicks=1)
{
     object response = null;

     string myJavaScript =

            // Callback (place in first!) used to notify the caller that the async callee is ready
            "  var callback = arguments[arguments.length - 1];                                           " +
            "  var maxIntervals = arguments[1];                                                          " +
            //ms
            "  var intervalDuration = 150;                                                               " +
            "  console.log('javascripting...', callback, arguments);                                     " +

            "var d = new Date();                                                                         " +
            "var n = d.getTime();                                                                        " +

            "  var myZoomCenterElement = document.getElementById('" + elemId + "');                      " +
            // some debug output in the console
            "  console.log(myZoomCenterElement);                                                         " +

            // *** THE CORE OF THE SOLUTION *** Creates proper WheelEvent object and triggers WheelEvent(Zoom)
            "  var box = myZoomCenterElement.getBoundingClientRect();                                    " +
            "  var boxMiddleX = Math.round((box.right + box.left )/2);                                   " +
            "  var boxMiddleY = Math.round((box.bottom + box.top )/2);                                   " +
            "  var myWheelableElement = document.getElementsByClassName('svg-tree-view')[0];             " +
            "  var wheelEventInitDict = {                                                                " +
            "               'deltaX'    :      0.0,                                                      " +
            "               'deltaY'    :   -200.0,                                                      " +
            "               'deltaZ'    :      0.0,                                                      " +
            "               'deltaMode' :        0,                                                      " +
            "               'clientX'   :        boxMiddleX,                                             " +
            "               'clientY'   :        boxMiddleY                                              " +
            "               };                                                                           " +
            "  var myWheelEvent = new WheelEvent('wheel', wheelEventInitDict);                           " +
            "  console.log(wheelEventInitDict, boxMiddleX, boxMiddleY, myWheelEvent);                    " +

            " var myIntervalCounter = 0;                                                                 " +
            " var myInterval = setInterval(function(){                                                   " +
            "                    myWheelableElement.dispatchEvent(myWheelEvent);                         " +
            "                    myIntervalCounter++;                                                    " +
            "                    if (myIntervalCounter > maxIntervals) clearInterval(myInterval);        " +
            "                }, intervalDuration);                                                       " +

            " var sthToReturn = 'Returning: Nothing requested!';                                         " +
            " var asyncAwaitInMiliSeconds = Math.ceil( 1.2 * intervalDuration * maxIntervals );          " +

            // Triggers the callback (to indicate async ready)
            " setTimeout( function(){                                                                    " +
            "                       console.log((new Date()).getTime()-n);                               " +
            "                       callback(sthToReturn);                                               " +
            "           }, asyncAwaitInMiliSeconds);                                                     " +

            ""
            ;
     _driver.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 0, 20));

     IJavaScriptExecutor js = _driver as IJavaScriptExecutor;
     try
     {
            // addititonal args(optional) to be sent to the javascript func are put after the first arg
            return response = js.ExecuteAsyncScript(myJavaScript, elemId, wheelTicks);

     }
     catch(UnhandledAlertException e)
     {
            Console.WriteLine("Error Occured! \n {0}", e.ToString() );
            return null;
     }
 }
</code>```

Body:
This is my implementation after investigating

//wheelTicks: negative for zoomin, positive to zoomout
public object zoomElementById(string elemId, int wheelTicks=1)
{
     object response = null;

     string myJavaScript =

            // Callback (place in first!) used to notify the caller that the async callee is ready
            "  var callback = arguments[arguments.length - 1];                                           " +
            "  var maxIntervals = arguments[1];                                                          " +
            //ms
            "  var intervalDuration = 150;                                                               " +
            "  console.log('javascripting...', callback, arguments);                                     " +

            "var d = new Date();                                                                         " +
            "var n = d.getTime();                                                                        " +

            "  var myZoomCenterElement = document.getElementById('" + elemId + "');                      " +
            // some debug output in the console
            "  console.log(myZoomCenterElement);                                                         " +

            // *** THE CORE OF THE SOLUTION *** Creates proper WheelEvent object and triggers WheelEvent(Zoom)
            "  var box = myZoomCenterElement.getBoundingClientRect();                                    " +
            "  var boxMiddleX = Math.round((box.right + box.left )/2);                                   " +
            "  var boxMiddleY = Math.round((box.bottom + box.top )/2);                                   " +
            "  var myWheelableElement = document.getElementsByClassName('svg-tree-view')[0];             " +
            "  var wheelEventInitDict = {                                                                " +
            "               'deltaX'    :      0.0,                                                      " +
            "               'deltaY'    :   -200.0,                                                      " +
            "               'deltaZ'    :      0.0,                                                      " +
            "               'deltaMode' :        0,                                                      " +
            "               'clientX'   :        boxMiddleX,                                             " +
            "               'clientY'   :        boxMiddleY                                              " +
            "               };                                                                           " +
            "  var myWheelEvent = new WheelEvent('wheel', wheelEventInitDict);                           " +
            "  console.log(wheelEventInitDict, boxMiddleX, boxMiddleY, myWheelEvent);                    " +

            " var myIntervalCounter = 0;                                                                 " +
            " var myInterval = setInterval(function(){                                                   " +
            "                    myWheelableElement.dispatchEvent(myWheelEvent);                         " +
            "                    myIntervalCounter++;                                                    " +
            "                    if (myIntervalCounter > maxIntervals) clearInterval(myInterval);        " +
            "                }, intervalDuration);                                                       " +

            " var sthToReturn = 'Returning: Nothing requested!';                                         " +
            " var asyncAwaitInMiliSeconds = Math.ceil( 1.2 * intervalDuration * maxIntervals );          " +

            // Triggers the callback (to indicate async ready)
            " setTimeout( function(){                                                                    " +
            "                       console.log((new Date()).getTime()-n);                               " +
            "                       callback(sthToReturn);                                               " +
            "           }, asyncAwaitInMiliSeconds);                                                     " +

            ""
            ;
     _driver.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 0, 20));

     IJavaScriptExecutor js = _driver as IJavaScriptExecutor;
     try
     {
            // addititonal args(optional) to be sent to the javascript func are put after the first arg
            return response = js.ExecuteAsyncScript(myJavaScript, elemId, wheelTicks);

     }
     catch(UnhandledAlertException e)
     {
            Console.WriteLine("Error Occured! \n {0}", e.ToString() );
            return null;
     }
 }


问:
String variable and echo (C) *Homework*
I am trying to solve this question: Write a C program that reads in characters from the keyboard until the return key is entered and echoes the entered text on the screen.

This is what I have so far, I am not sure what variable I can store the users input in so that I can print it back (assuming that is what they mean by echo):

```<code>#include<stdio.h>
#include<string>
int main ()
{
    char sentence;
    printf("Please enter anything you want: ");
    scanf("%c",&sentence);

    printf("%c",sentence);

    return 0;
}
</code>```

答:
You could try using getchar which returns a single character from stdin.

```<code>int character;
while (character != EOF && character != '\n') {
    character = getchar();
    putchar(character);
}
</code>```

Alternatively, you can make an assignment inside the while loop.

```<code>int character;
while ((character = getchar()) != EOF && character != '\n')
    putchar(character);
</code>```

Title: String variable and echo (C) *Homework*

Body:
I am trying to solve this question: Write a C program that reads in characters from the keyboard until the return key is entered and echoes the entered text on the screen.

This is what I have so far, I am not sure what variable I can store the users input in so that I can print it back (assuming that is what they mean by echo):

#include<stdio.h>
#include<string>
int main ()
{
    char sentence;
    printf("Please enter anything you want: ");
    scanf("%c",&sentence);

    printf("%c",sentence);

    return 0;
}

Body:
You could try using getchar which returns a single character from stdin.

int character;
while (character != EOF && character != '\n') {
    character = getchar();
    putchar(character);
}

Alternatively, you can make an assignment inside the while loop.

int character;
while ((character = getchar()) != EOF && character != '\n')
    putchar(character);


问:
How to change results in Access query?
I have a table, we'll call it users.

```<code>id username type
</code>```

The type field is a two character type, so each user either has US, MO, AD.  Not sure why the original developer did this, but I cannot change this method, unfortunately.

```<code>1 mike US
2 Tim AD
3 mark MO
</code>```

Instead of returning US, AD... etc types in Access, I'd like the query to replace the US with USER, replace MO with MODERATOR, and replace AD with ADMIN.

Is this possible?

Kind of like SELECT * FROM USERS and then if statements within Access (if US, then USER).  Not sure how to proceed?

答:
Sure thing!  Try something along these lines:
select [id], [username],
iif([type] = "US", "User",
  iif([type] = "MO", "Moderator",
    iif([type] = "AD", "Admin", "Unknown Type"
  )
)

(Here's a link to the IIf function)

All things considered, though, you may want to normalize your data with a lookup table.  So, for example, create a second table called, "UserType" with two columns: [Code] and [Name].  Then populate it with three records:
"US", "User"
"MO", "Moderator"
"AD", "Admin"

Then, within query designer, include both tables and join them by dragging the "type" column from your source table to the "[Code]" column on the [UserType] table.  Then, select the [id] and [username] columns from the first table, and the [name] column from the lookup table.  That way, if you need to add new user types, you don't have to worry about going back and modifying all of your queries.

ContentLicense: CC BY-SA 2.5

Title: How to change results in Access query?

Body:
I have a table, we'll call it users.

id username type

The type field is a two character type, so each user either has US, MO, AD.  Not sure why the original developer did this, but I cannot change this method, unfortunately.

1 mike US
2 Tim AD
3 mark MO

Instead of returning US, AD... etc types in Access, I'd like the query to replace the US with USER, replace MO with MODERATOR, and replace AD with ADMIN.

Is this possible?

Kind of like SELECT * FROM USERS and then if statements within Access (if US, then USER).  Not sure how to proceed?


问:
What to put in the parameters of the EditText constructor in Android Studio?
I'm still fairly new to Android Studio and I want to test out something by creating a GridLayout with the desired rows and columns and fill it up with EditTexts. However I run into a problem where I do not know what to put as a parameter in the EditText constructor.
Here is the java code below:

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

    //The numbers WILL vary but this is just a test
    int rows = 3;
    int columns = 4;

    GridLayout gd = (GridLayout) findViewById(R.id.grid1);
    gd.setRowCount(rows);
    gd.setColumnCount(columns);
    EditText edt;

    for(int r = 0; r < rows; r++)
    {
        for(int c = 0; c < columns; c++)
        {
            //What to put in the parameters in this code below?
            edt = new EditText();
            gd.addView(edt);
        }
    }
}
</code>```

And here is the XML:

```<code><GridLayout
        android:id="@+id/grid1"
        android:layout_width="368dp"
        android:layout_height="495dp"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp">

</GridLayout>
</code>```

I looked at the constructor for EditText and find that Context is needed, but how do I put that in there? If this is not the right way to do it, please tell me the right way.

答: Every Activity is a Context.  For Views, you pass in either the Activity you're in, or the parent's Context (via getContext()) depending on what's more convenient.  Here generally it would be the Activity, so you pass in this.</p>

Body:
I'm still fairly new to Android Studio and I want to test out something by creating a GridLayout with the desired rows and columns and fill it up with EditTexts. However I run into a problem where I do not know what to put as a parameter in the EditText constructor.
Here is the java code below:

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

    //The numbers WILL vary but this is just a test
    int rows = 3;
    int columns = 4;

    GridLayout gd = (GridLayout) findViewById(R.id.grid1);
    gd.setRowCount(rows);
    gd.setColumnCount(columns);
    EditText edt;

    for(int r = 0; r < rows; r++)
    {
        for(int c = 0; c < columns; c++)
        {
            //What to put in the parameters in this code below?
            edt = new EditText();
            gd.addView(edt);
        }
    }
}

And here is the XML:

<GridLayout
        android:id="@+id/grid1"
        android:layout_width="368dp"
        android:layout_height="495dp"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp">

</GridLayout>

I looked at the constructor for EditText and find that Context is needed, but how do I put that in there? If this is not the right way to do it, please tell me the right way.


问:
Ubuntu Cron Job Screen
I am trying to run a program that runs this line of code in

screen livestream_dl -u "..." "..."

And it then starts a process of checking if an Instagram Live video is being active then Downloads it if it can find it and if not the screen terminates.

My issue is I have placed this into the cron job by adding this

```<code>*/1   *    *    *    *     screen livestream_dl "name" "igname" -p "pass"
</code>```

Firstly, should I leave it as screen or without screen which would work to get the result if I were to do the same through SSH command line

Secondly, how can I improve this cron job to make sure if the Cronjob is already running then to ignore the command and check again in a minute?

Thanks very much! :)

答:
You should definitely remove screen. screen is used to make terminal session resumable from another TTY. Since a cron job is not interactive by definition you won't need it.

In order to prevent cron from starting two instances of the job at the same time you can use flock. flock will create a semaphore file on the first run. If such a file is found it will either wait for the semaphore to be removed or terminate immediately if you specify the nonblack option. The later is probably what you want.

Title: Ubuntu Cron Job Screen

Body:
I am trying to run a program that runs this line of code in

screen livestream_dl -u "..." "..."

And it then starts a process of checking if an Instagram Live video is being active then Downloads it if it can find it and if not the screen terminates.

My issue is I have placed this into the cron job by adding this

*/1   *    *    *    *     screen livestream_dl "name" "igname" -p "pass"

Firstly, should I leave it as screen or without screen which would work to get the result if I were to do the same through SSH command line

Secondly, how can I improve this cron job to make sure if the Cronjob is already running then to ignore the command and check again in a minute?

Thanks very much! :)


问:
Partially fill object when hovering
I have code below for a content cycle I have created with the help from some other Stack Overflow users. Is it possible to have the circular arrow fill up partially depending on what box your hovered on. Example: If the user hovers on box four (the bottom box) the circular arrow would fill up with a different color only up until that box. Is this possible to do with pure CSS only? If not would this be possible with vanilla JavaScript (no Jquery)? Anything helps, cheers.

.container .row {
  text-align: center;
  position: relative;
}

.row {
  position: relative;
}

.one {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
}

.one:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.two {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
  margin-left: -35px;
}

.two:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.three {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
  margin-left: -35px;
}

.three:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.four {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
}

.four:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.five {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
}

.five:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.six {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
}

.six:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.circle {
  display: inline-block;
  background-color: #006850;
  width: 85px;
  height: 85px;
  border-width: 3px;
  border-style: solid;
  border-color: #fefefe;
  border-radius: 50%;
  box-shadow: 0px 1px 5px #888888;
  margin-bottom: -15px;
}

.invisible {
  visibility: hidden;
  display: inline-block;
  background-color: #1f497d;
  width: 130px;
  height: 65px;
  border-width: 3px;
  border-style: solid;
  border-color: #d6d6d6;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
}

.arrow {
  color: #d0d3d8;
  width: 250px;
  height: 250px;
  border: 17px solid;
  border-radius: 50%;
  position: absolute;
  top: 15px;
  left: 50%;
  transform: translate(-50%, 0);
  z-index: -1;
}

.arrow:before {
  content: "";
  display: block;
  width: 30px;
  height: 30px;
  position: absolute;
  bottom: 0;
  top: -10px;
  left: 55px;
  background: #fff;
  transform: rotate(-120deg);
}

.arrow:after {
  content: "";
  width: 0;
  height: 0;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
  border-top: 20px solid #d0d3d8;
  position: absolute;
  top: 0px;
  left: 40px;
  transform: rotate(-120deg);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <div class="row">
    <div class="one"></div>
  </div>
  <div class="row" style="margin-top:-15px;">
    <div class="six"></div>
    <div class="invisible"></div>
    <div class="two"></div>
  </div>
  <div class="row" style="margin-top:-15px;">
    <div class="invisible"></div>
    <div class="circle"></div>
    <div class="invisible"></div>
  </div>
  <div class="row" style="margin-top:-15px;">
    <div class="five"></div>
    <div class="invisible"></div>
    <div class="three"></div>
  </div>
  <div class="row">
    <div class="four"></div>
  </div>
  <div class="arrow"></div>
</div></code>```

答:
I have fully changed your layout.

Now everything works ok. And also, making changes in the position will be easier.

.container {
  width: 250px;
  height: 250px;
  position: absolute;
  top: 45px;
  left: 0px;
  right: 0px;
  margin: auto;
}

.ele, .arrow, .circle {
   position: absolute;
   left: 0px;
   right: 0px;
   top: 0px;
   bottom: 0px;
   margin: auto;
}

#one {
    transform: rotate(0deg) translateY(-130px) rotate(0deg);
}
#two {
    transform: rotate(60deg) translateY(-130px) rotate(-60deg);
}
#three {
    transform: rotate(120deg) translateY(-130px) rotate(-120deg);
}
#four {
    transform: rotate(180deg) translateY(-130px) rotate(-180deg);
}
#five {
    transform: rotate(240deg) translateY(-130px) rotate(-240deg);
}
#six {
    transform: rotate(300deg) translateY(-130px) rotate(-300deg);
}

.ele {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
}

.ele:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.circle {
  background-color: #006850;
  width: 85px;
  height: 85px;
  border-width: 3px;
  border-style: solid;
  border-color: #fefefe;
  border-radius: 50%;
  box-shadow: 0px 1px 5px #888888;
}

.arrow {
  color: #d0d3d8;
  width: 250px;
  height: 250px;
  border: 17px solid;
  border-radius: 50%;
  position: absolute;
  z-index: -3;
  left: -17px;
}

#two:hover ~ .arrow {
  border-top-color: red;
  transform: rotate(24deg);
}
#three:hover ~ .arrow {
  border-top-color: red;
  transform: rotate(66deg);
}
#four:hover ~ .arrow {
  border-top-color: red;
  border-right-color: red;
  transform: rotate(25deg);
}
#five:hover ~ .arrow {
  border-top-color: red;
  border-right-color: red;
  border-bottom-color: red;
  transform: rotate(26deg);
}
#six:hover ~ .arrow {
  border-top-color: red;
  border-right-color: red;
  border-bottom-color: red;
  transform: rotate(66deg);
}
#one:hover ~ .arrow {
  border-color: red;
}
#one:hover ~ .circle:after {
  border-top-color: red;
}

.circle:before {
  content: "";
  display: block;
  width: 30px;
  height: 30px;
  position: absolute;
  bottom: 0;
  top: -96px;
  left: -36px;
  background: #fff;
  background-color: white;
  transform: rotate(-120deg);
  z-index: -1;
}

.circle:after {
  content: "";
  width: 0;
  height: 0;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
  border-top: 20px solid #d0d3d8;
  position: absolute;
  top: -83px;
  left: -44px;
  transform: rotate(-120deg);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
    <div class="ele" id="one">1</div>
    <div class="ele" id="two">2</div>
    <div class="ele" id="three">3</div>
    <div class="ele" id="four">4</div>
    <div class="ele" id="five">5</div>
    <div class="ele" id="six">6</div>
    <div class="arrow"></div>
    <div class="circle"></div>
</div></code>```

Title: Partially fill object when hovering

Body:
I have fully changed your layout.

Now everything works ok. And also, making changes in the position will be easier.

.container {
  width: 250px;
  height: 250px;
  position: absolute;
  top: 45px;
  left: 0px;
  right: 0px;
  margin: auto;
}

.ele, .arrow, .circle {
   position: absolute;
   left: 0px;
   right: 0px;
   top: 0px;
   bottom: 0px;
   margin: auto;
}

#one {
    transform: rotate(0deg) translateY(-130px) rotate(0deg);
}
#two {
    transform: rotate(60deg) translateY(-130px) rotate(-60deg);
}
#three {
    transform: rotate(120deg) translateY(-130px) rotate(-120deg);
}
#four {
    transform: rotate(180deg) translateY(-130px) rotate(-180deg);
}
#five {
    transform: rotate(240deg) translateY(-130px) rotate(-240deg);
}
#six {
    transform: rotate(300deg) translateY(-130px) rotate(-300deg);
}

.ele {
  display: inline-block;
  background-color: #1f497d;
  width: 100px;
  height: 50px;
  border-width: 3px;
  border-style: solid;
  border-color: #ededed;
  border-radius: 7px;
  box-shadow: 0px 1px 5px #888888;
}

.ele:hover {
  cursor:pointer;
  transform:scale(1.019);
  border-color:f4f4f4;
  background-color:#214d84;
  box-shadow: 0px 2px 9px #888888;
}

.circle {
  background-color: #006850;
  width: 85px;
  height: 85px;
  border-width: 3px;
  border-style: solid;
  border-color: #fefefe;
  border-radius: 50%;
  box-shadow: 0px 1px 5px #888888;
}

.arrow {
  color: #d0d3d8;
  width: 250px;
  height: 250px;
  border: 17px solid;
  border-radius: 50%;
  position: absolute;
  z-index: -3;
  left: -17px;
}

#two:hover ~ .arrow {
  border-top-color: red;
  transform: rotate(24deg);
}
#three:hover ~ .arrow {
  border-top-color: red;
  transform: rotate(66deg);
}
#four:hover ~ .arrow {
  border-top-color: red;
  border-right-color: red;
  transform: rotate(25deg);
}
#five:hover ~ .arrow {
  border-top-color: red;
  border-right-color: red;
  border-bottom-color: red;
  transform: rotate(26deg);
}
#six:hover ~ .arrow {
  border-top-color: red;
  border-right-color: red;
  border-bottom-color: red;
  transform: rotate(66deg);
}
#one:hover ~ .arrow {
  border-color: red;
}
#one:hover ~ .circle:after {
  border-top-color: red;
}

.circle:before {
  content: "";
  display: block;
  width: 30px;
  height: 30px;
  position: absolute;
  bottom: 0;
  top: -96px;
  left: -36px;
  background: #fff;
  background-color: white;
  transform: rotate(-120deg);
  z-index: -1;
}

.circle:after {
  content: "";
  width: 0;
  height: 0;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
  border-top: 20px solid #d0d3d8;
  position: absolute;
  top: -83px;
  left: -44px;
  transform: rotate(-120deg);
}

<div class="container">
    <div class="ele" id="one">1</div>
    <div class="ele" id="two">2</div>
    <div class="ele" id="three">3</div>
    <div class="ele" id="four">4</div>
    <div class="ele" id="five">5</div>
    <div class="ele" id="six">6</div>
    <div class="arrow"></div>
    <div class="circle"></div>
</div>


问:
Can I determine the order of validation error messages in Rails?
I want to get the order of validation messages to go in the same order as they do on our form.

We have three classes:

```<code>class User
  accepts_nested_attributes_for :pledges
end

class Pledge
  accepts_nested_attributes_for :companies
  validates_presence_of :pledgor_surname
end

class Company
  validates_presence_of :name
end
</code>```

In one form, we potentially have to take attributes for all three, so we get params like the following:

```<code>{"pledges_attributes"=>
  {"0"=>
    {"pledgor_surname"=>"",
     "id"=>"230",
     "companies_attributes"=>
      {"0"=>
        {"id"=>"125",
         "name"=>""
        }
      }
    }
  }
}
</code>```

When I call @user.update(params), it fails validation as I'd expect. But the errors#full_messages list looks like this:

```<code>["Company name can't be blank", "Pledgor surname can't be blank"]`
</code>```

And the errors appear on the page in the same order.

Short of hacking the messages object, is there a way to tell Rails which order to place the messages in, or at least which of pledgor errors and company errors should go first?

答:
No, they are returned in a hash and hashes do not provide reliable ordering. This could be overridden, which is typically done by adding files to the lib folder and specifying your overrides in the rails config.

Edit According to the comment below since Ruby 1.9.3, hashes are actually ordered, so ignore what I said.

Body:
I want to get the order of validation messages to go in the same order as they do on our form.

We have three classes:

class User
  accepts_nested_attributes_for :pledges
end

class Pledge
  accepts_nested_attributes_for :companies
  validates_presence_of :pledgor_surname
end

class Company
  validates_presence_of :name
end

In one form, we potentially have to take attributes for all three, so we get params like the following:

{"pledges_attributes"=>
  {"0"=>
    {"pledgor_surname"=>"",
     "id"=>"230",
     "companies_attributes"=>
      {"0"=>
        {"id"=>"125",
         "name"=>""
        }
      }
    }
  }
}

When I call @user.update(params), it fails validation as I'd expect. But the errors#full_messages list looks like this:

["Company name can't be blank", "Pledgor surname can't be blank"]`

And the errors appear on the page in the same order.

Short of hacking the messages object, is there a way to tell Rails which order to place the messages in, or at least which of pledgor errors and company errors should go first?


问:
Replace only specific group in file form preg_replace
I have txt file with content:

```<code>fggfhfghfghf

$config['website'] = 'Olpa';

asdasdasdasdasdas
</code>```

And PHP script for replacing by preg_replace in file:

```<code>write_file('tekst.txt', preg_replace('/\$config\[\'website\'] = \'(.*)\';/', 'aaaaaa', file_get_contents('tekst.txt')));
</code>```

But it doesn't work exactly what I want it to work.

Because this script replace whole match, and after change it looks like this:

```<code>fggfhfghfghf

aaaaaa

asdasdasdasdasdas
</code>```

And that's bad.

All I want is to not change whole match $config['website'] = 'Olpa'; But to just change this Olpa

As you can see it belongs not to Group 2. of match information.

And all I want is to just change this Group 2. one specific thing.

to finally after script it will look like:

```<code>fggfhfghfghf

$config['website'] = 'aaaaaa';

asdasdasdasdasdas
</code>```

答:
You need to change your preg_replace to

```<code>preg_replace('/(\$config\[\'website\'] = \').*?(\';)/', '$1aaaaaa$2', file_get_contents('tekst.txt'))
</code>```

It means, capture what you need to keep (and then use backreferences to restore the text) and just match what you need to replace.

See the regex demo.

Pattern details:

(\$config\[\'website\'] = \') - Group 1 capturing a literal  $config['website'] = ' substring (later referenced to with $1)

.*? - any 0+ chars other than line break chars as few as possible

(\';) - Group 2: a ' followed with ; (later referenced to with $2)

In case your aaa actually starts with a digit, you would need a ${1}  backreference.

Body:
I have txt file with content:

fggfhfghfghf

$config['website'] = 'Olpa';

asdasdasdasdasdas

And PHP script for replacing by preg_replace in file:

write_file('tekst.txt', preg_replace('/\$config\[\'website\'] = \'(.*)\';/', 'aaaaaa', file_get_contents('tekst.txt')));

But it doesn't work exactly what I want it to work.

Because this script replace whole match, and after change it looks like this:

fggfhfghfghf

aaaaaa

asdasdasdasdasdas

And that's bad.

All I want is to not change whole match $config['website'] = 'Olpa'; But to just change this Olpa

As you can see it belongs not to Group 2. of match information.

And all I want is to just change this Group 2. one specific thing.

to finally after script it will look like:

fggfhfghfghf

$config['website'] = 'aaaaaa';

asdasdasdasdasdas

Body:
You need to change your preg_replace to

preg_replace('/(\$config\[\'website\'] = \').*?(\';)/', '$1aaaaaa$2', file_get_contents('tekst.txt'))

It means, capture what you need to keep (and then use backreferences to restore the text) and just match what you need to replace.

See the regex demo.

Pattern details:

(\$config\[\'website\'] = \') - Group 1 capturing a literal  $config['website'] = ' substring (later referenced to with $1)

.*? - any 0+ chars other than line break chars as few as possible

(\';) - Group 2: a ' followed with ; (later referenced to with $2)

In case your aaa actually starts with a digit, you would need a ${1}  backreference.


问:
Calling variable in user-defined function with reshape2::melt and reshape2::dcast
I would like to convert this data frame

```<code>data <- data.frame(color=c("red","red","red","green","green","green","blue","blue","blue"),object=c("box","chair","table","box","chair","table","box","chair","table"),units=c(1:9),price=c(11.5,12.5,13.5,14.5,15.5,16.5,17.5,18.5,19.5))
</code>```

to this other one

```<code>output <- data.frame(color=c("red","green","blue"),units_box=c(1,4,7),price_box=c(11.5,14.5,17.5), units_chair=c(2,5,8),price_chair=c(12.5,15.5,18.5),units_table=c(3,6,9),price_table=c(13.5,16.5,19.5))
</code>```

Therefore, I am using reshape2::melt and reshape2::dcast to build a user-defined function as the following

```<code>fun<-function(df,var,group){
  r<-reshape2::melt(df,id.vars=var)
  r<-reshape2::dcast(r,var~group)
return(r)
}
</code>```

When I use the function as follows

fun(data,color,object)

I get the following error message

Error in melt_check(data, id.vars, measure.vars, variable.name,
  value.name) : object 'color' not found

Do you know how can I solve it? I think that the problem is that I should call the variables in reshape2::melt with quotes but I do not know how.

Note 1: I would like keep the original number format of variables (i.e. objects without decimals and price with one decimal)

Note 2: I would like to remark that that my real code (this is just a simplified example) is much longer and involves dplyr functions (including enquo() and UQ() functions). Therefore the solutions for this case should be compatible with dplyr.

Note 3: I do not use tidyr (I am a big fun of the whole tidyverse) because the current tidyr still use the old language for functions and I share the script with other people that might not be willing to use the development version of tidyr.

答:
I solved the issue by myself (although I do not know very well the reasons behind).
The main problem, as I suspected was passing the variables of the user-defined function in melt and dcast cause some kind of conflict maybe due to the lack of quotes (?).
Anyway I renamed the variables using dplyr::rename so that the names are not anymore depended of variables but characters. Here you can see the final code I am applying:

```<code>fun<-function(df,var,group){
  enquo_var<-enquo(var)
  enquo_group<-enquo(group)

  r<-df%>%
    reshape2::melt(., id.var=1, variable.name = "parameter")%>%
    dplyr::rename(var = UQ(enquo_var))%>%
    reshape2::dcast(data=., formula = var~parameter, value.var = "value")

return(r)
}

funx<-fun(data,color,object)
</code>```

Although I found the solution to my particular problem, I would appreciate very much if someone explains me the reasons behind.

PS: I hope anyway that the new version of tidyr is ready soon to make such tasks easier. Thanks @hadley for your fantastic work.

Body:
I would like to convert this data frame

data <- data.frame(color=c("red","red","red","green","green","green","blue","blue","blue"),object=c("box","chair","table","box","chair","table","box","chair","table"),units=c(1:9),price=c(11.5,12.5,13.5,14.5,15.5,16.5,17.5,18.5,19.5))

to this other one

output <- data.frame(color=c("red","green","blue"),units_box=c(1,4,7),price_box=c(11.5,14.5,17.5), units_chair=c(2,5,8),price_chair=c(12.5,15.5,18.5),units_table=c(3,6,9),price_table=c(13.5,16.5,19.5))

Therefore, I am using reshape2::melt and reshape2::dcast to build a user-defined function as the following

fun<-function(df,var,group){
  r<-reshape2::melt(df,id.vars=var)
  r<-reshape2::dcast(r,var~group)
return(r)
}

When I use the function as follows

fun(data,color,object)

I get the following error message

Error in melt_check(data, id.vars, measure.vars, variable.name,
  value.name) : object 'color' not found

Do you know how can I solve it? I think that the problem is that I should call the variables in reshape2::melt with quotes but I do not know how.

Note 1: I would like keep the original number format of variables (i.e. objects without decimals and price with one decimal)

Note 2: I would like to remark that that my real code (this is just a simplified example) is much longer and involves dplyr functions (including enquo() and UQ() functions). Therefore the solutions for this case should be compatible with dplyr.

Note 3: I do not use tidyr (I am a big fun of the whole tidyverse) because the current tidyr still use the old language for functions and I share the script with other people that might not be willing to use the development version of tidyr.

Body:
I solved the issue by myself (although I do not know very well the reasons behind).
The main problem, as I suspected was passing the variables of the user-defined function in melt and dcast cause some kind of conflict maybe due to the lack of quotes (?).
Anyway I renamed the variables using dplyr::rename so that the names are not anymore depended of variables but characters. Here you can see the final code I am applying:

fun<-function(df,var,group){
  enquo_var<-enquo(var)
  enquo_group<-enquo(group)

  r<-df%>%
    reshape2::melt(., id.var=1, variable.name = "parameter")%>%
    dplyr::rename(var = UQ(enquo_var))%>%
    reshape2::dcast(data=., formula = var~parameter, value.var = "value")

return(r)
}

funx<-fun(data,color,object)

Although I found the solution to my particular problem, I would appreciate very much if someone explains me the reasons behind.

PS: I hope anyway that the new version of tidyr is ready soon to make such tasks easier. Thanks @hadley for your fantastic work.