问:
An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll Additional information: Input string was not in a correct format
I'm trying to insert a form data into database but there is some problem with the code that I'm unable to identify it. The Error is:

An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll

  Additional information: Input string was not in a correct format.

Winform code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MobShopManagSys
{
    public partial class Product_AddForm : Form
    {
        ProductsDB db = new ProductsDB();
        public Product_AddForm()
        {
            InitializeComponent();
        }
        private void SaveButton_Click(object sender, EventArgs e)
        {
            if (IsValidated()) //Proceed if required data is entered
            {
                db.InsertProductInDB(NameTextBox.Text, Convert.ToInt32(CategoryComboBox.SelectedValue), ModelTextBox.Text, SeriesComboBox.Text, Convert.ToInt32(SIMSlotsComboBox.Text), CarrierTypeComboBox.Text, GetReleaseDate(), Convert.ToInt32(RAMTextBox.Text), RAMMemUnitComboBox.Text, Convert.ToInt32(SecondryMemTextBox.Text), SecondMemUnitComboBox.Text, Convert.ToInt32(ExpandableTextBox.Text), ExpandableMemUnitComboBox.Text, OSVersionComboBox.Text, ProcessorComboBox.Text, ScreenSizeTextBox.Text, ScreenSizeTypeComboBox.Text, Convert.ToInt32(BatteryTextBox.Text), BatteryTypeComboBox.Text, CommentsTextBox.Text, Convert.ToInt32(SupplierComboBox.SelectedValue), float.Parse(PriceTextBox.Text), PriceUnitComboBox.Text, Convert.ToInt32(QuantityTextBox.Text), SaveProductPhoto());
                MessageBox.Show("New Record is added successfully!", "Record Added", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void AddSupplierButton_Click(object sender, EventArgs e)
        {
            Suppliers_AddForm AddNewSupplierFrm = new Suppliers_AddForm();
            AddNewSupplierFrm.ShowDialog();
            //Reload Data into control
            LoadFormControlsData();

        }
        private void ResetButton_Click(object sender, EventArgs e)
        {
            NameTextBox.Clear();
            CategoryComboBox.Text = " ";
            ModelTextBox.Clear();
            SeriesComboBox.Text = null;
            CarrierTypeComboBox.Text = null;
            SIMSlotsComboBox.Text = null;
            ReleaseDateTimePicker.CustomFormat = " ";

            RAMTextBox.Clear();
            RAMMemUnitComboBox.Text = null;
            SecondryMemTextBox.Clear();
            SecondMemUnitComboBox.Text = null;
            ExpandableTextBox.Clear();
            ExpandableMemUnitComboBox.Text = null;

            OSVersionComboBox.Text = null;
            ProcessorComboBox.Text = null;
            ScreenSizeTextBox.Clear();
            ScreenSizeTypeComboBox.Text = null;
            BatteryTextBox.Clear();
            BatteryTypeComboBox.Text = null;

            CommentsTextBox.Clear();

            SupplierComboBox.Text = null;
            PriceTextBox.Clear();
            PriceUnitComboBox.Text = null;
            QuantityTextBox.Clear();

            SystemSounds.Beep.Play();
            NameTextBox.Focus();
        }
        private void Product_AddForm_Load(object sender, EventArgs e)
        {
            LoadFormControlsData();
        }

        private void LoadFormControlsData()
        {
            CategoryComboBox.DataSource = db.LoadCategoryComboBox();
            CategoryComboBox.DisplayMember = "CategoryName";
            CategoryComboBox.ValueMember = "CategoryID";
            CategoryComboBox.SelectedIndex = -1;

            SeriesComboBox.DataSource = db.LoadSeriesComboBox();
            SeriesComboBox.DisplayMember = "Series";

            SupplierComboBox.DataSource = db.LoadSupplierComboBox();
            SupplierComboBox.DisplayMember = "Name";
            SupplierComboBox.ValueMember = "SupplierID";
            SupplierComboBox.SelectedIndex = -1;
        }
        private void AddNewCategoryButton_Click(object sender, EventArgs e)
        {
            Categories_AddForm AddCategoryFrm = new Categories_AddForm();
            AddCategoryFrm.ShowDialog();

            LoadFormControlsData();
        }
        private void ProductImagePictureBox_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Select the Image";
            ofd.Filter = "Image File (*.png;*.jpg;*.bmp;*.gif)|*.png;*.jpg;*.bmp;*.gif";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                ProductImagePictureBox.Image = new Bitmap(ofd.FileName);
            }
        }
        private byte[] SaveProductPhoto()
        {
            MemoryStream ms = new MemoryStream();
            ProductImagePictureBox.Image.Save(ms, ProductImagePictureBox.Image.RawFormat);
            return ms.GetBuffer();
        }
    private bool IsValidated()  //Validation Method Defination
        {
            if (NameTextBox.Text.Trim() == "")
            {
                ValidationMessage(NameTextBox, "Name is required!");
                return false;
            }
            if (CategoryComboBox.Text.Trim() == "")
            {
                ValidationMessage(CategoryComboBox, "Please select the Category/Brand!");
                return false;
            }
            if (ModelTextBox.Text.Trim() == "")
            {
                ValidationMessage(ModelTextBox, "Model is required!");
                return false;
            }
            if (RAMTextBox.Text.Trim() == "")
            {
                ValidationMessage(RAMTextBox, "RAM memory required!");
                return false;
            }
            else
            {
                float outRAM;
                if(!float.TryParse(RAMTextBox.Text, out outRAM))
                {
                    ValidationMessage(RAMTextBox, "RAM field only contain numbers!");
                    return false;
                }
            }
            if (RAMMemUnitComboBox.Text.Trim() == "")
            {
                ValidationMessage(RAMMemUnitComboBox, "Please select a Memory Unit!");
                return false;
            }

            if (SecondryMemTextBox.Text.Trim() == "")
            {
                ValidationMessage(SecondryMemTextBox, "Secondry memory field is required!");
                return false;
            }
            else
            {
                float outSecMem;
                if (!float.TryParse(RAMTextBox.Text, out outSecMem))
                {
                    ValidationMessage(RAMTextBox, "Secondry memory field only contain numbers!");
                    return false;
                }
            }
            if (SecondMemUnitComboBox.Text.Trim() == "")
            {
                ValidationMessage(SecondMemUnitComboBox, "Please select a Memory Unit!");
                return false;
            }
            if (ExpandableTextBox.Text != "")
            {
                int outexpmem;
                if (!int.TryParse(ExpandableTextBox.Text, out outexpmem))
                {
                    ValidationMessage(ExpandableTextBox, "Expandable memory can only numbers!");
                    return false;
                }
              if (ExpandableMemUnitComboBox.Text.Trim() == "")
                {
                    ValidationMessage(ExpandableMemUnitComboBox, "Please select a Memory Unit!");
                    return false;
                }
            }
            if (OSVersionComboBox.Text.Trim() == "")
            {
                ValidationMessage(OSVersionComboBox, "OS Version selection is required!");
                return false;
            }
            if (BatteryTextBox.Text.Trim() == "")
            {
                ValidationMessage(BatteryTextBox, "Battery Capacity required!");
                return false;
            }
            if (BatteryTypeComboBox.Text.Trim() == "")
            {
                ValidationMessage(BatteryTypeComboBox, "Please select a Battery Capacity Unit!");
                return false;
            }
            if(PriceTextBox.Text != "" )
            {
                float outexpmem;
                if (!float.TryParse(PriceTextBox.Text, out outexpmem))
                {
                    ValidationMessage(PriceTextBox, "Purchase Price only numbers!");
                    return false;
                }
              if (PriceUnitComboBox.Text.Trim() == "")
                {
                    ValidationMessage(PriceUnitComboBox, "Please select Currency Unit!");
                    return false;
                }
            }

            if (QuantityTextBox.Text.Trim() == "")
            {
                ValidationMessage(QuantityTextBox, "Quantity of Product is required!");
                return false;
            }
            else
            {
                int outQuantity;
                if (!int.TryParse(QuantityTextBox.Text, out outQuantity))
                {
                    ValidationMessage(QuantityTextBox, "Quantity can only in numbers!");
                    return false;
                }
             }
            return true;
            }

        private void ValidationMessage(Control ctrl, string ValidationMsg) //Validation Message Def.
        {
            ctrl.BackColor = Color.LightPink;
            MessageBox.Show(ValidationMsg, "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            ctrl.Focus();
        }

        private void ctrl_TextChanged(object sender, EventArgs e) //Back change color to white
        {
            Control ctrl = (Control)sender;
            ctrl.BackColor = Color.White;
        }
        private void ClearCommentsButton_Click(object sender, EventArgs e)
        {
            CommentsTextBox.Clear();
            CommentsTextBox.Focus();
        }
        //Date Time Picker   <Start>
        private void ReleaseDateTimePicker_ValueChanged(object sender, EventArgs e)
        {
            ReleaseDateTimePicker.CustomFormat = "dd/MM/yyyy";
        }

        private void ReleaseDateTimePicker_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode==Keys.Back || e.KeyCode == Keys.Delete)
            {
                ReleaseDateTimePicker.CustomFormat = " ";
            }
        }
        private DateTime? GetReleaseDate()
        {
            if (ReleaseDateTimePicker.Text.Trim() == string.Empty)
            {
                return (DateTime?)null;
            }
            else
                return ReleaseDateTimePicker.Value.Date;
        }

    }  //Date Time Picker   <End>

}
```

<p>Error in this line of code:</p>

```db.InsertProductInDB(NameTextBox.Text, Convert.ToInt32(CategoryComboBox.SelectedValue), ModelTextBox.Text, SeriesComboBox.Text, Convert.ToInt32(SIMSlotsComboBox.Text), CarrierTypeComboBox.Text, GetReleaseDate(), Convert.ToInt32(RAMTextBox.Text), RAMMemUnitComboBox.Text, Convert.ToInt32(SecondryMemTextBox.Text), SecondMemUnitComboBox.Text, Convert.ToInt32(ExpandableTextBox.Text), ExpandableMemUnitComboBox.Text, OSVersionComboBox.Text, ProcessorComboBox.Text, ScreenSizeTextBox.Text, ScreenSizeTypeComboBox.Text, Convert.ToInt32(BatteryTextBox.Text), BatteryTypeComboBox.Text, CommentsTextBox.Text, Convert.ToInt32(SupplierComboBox.SelectedValue), float.Parse(PriceTextBox.Text), PriceUnitComboBox.Text, Convert.ToInt32(QuantityTextBox.Text), SaveProductPhoto());
```

<h3>Database Class Code</h3>

<pre class="lang-cs prettyprint-override"><code>using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MobShopManagSys
{
    class ProductsDB
    {
        string connString = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;

        //Add Product Form
        public void InsertProductInDB(string Name, int CategoryID, string Model, string Series, int SIMSlots, string CarrierType, DateTime? ReleaseDate, int RAM, string RAMMemUnit, int SecondryMem, string SecondMemUnit, int Expandable, string ExpandableMemUnit, string OSVersion, string Processor, string ScreenSize, string ScreenSizeType, int Battery, string BatteryType, string Comments, int SupplierID, float Price, string PriceUnit, int UnitsInStock, byte[] SaveProductPhoto)
        {
            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand cmd = new SqlCommand("spProducts_InsertProduct", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    //Parameters
                    cmd.Parameters.AddWithValue("@Name", Name);
                    cmd.Parameters.AddWithValue("@CategoryID", CategoryID);
                    cmd.Parameters.AddWithValue("@Model", Model);
                    cmd.Parameters.AddWithValue("@Series", Series);
                    cmd.Parameters.AddWithValue("@SIMSlots", SIMSlots);
                    cmd.Parameters.AddWithValue("@CarrierType", CarrierType);
                    cmd.Parameters.AddWithValue("@ReleaseDate", ReleaseDate);
                    cmd.Parameters.AddWithValue("@RAM", RAM);
                    cmd.Parameters.AddWithValue("@RAMMemUnit", RAMMemUnit);
                    cmd.Parameters.AddWithValue("@SecondryMem", SecondryMem);
                    cmd.Parameters.AddWithValue("@SecondMemUnit", SecondMemUnit);
                    cmd.Parameters.AddWithValue("@Expandable", Expandable);
                    cmd.Parameters.AddWithValue("@ExpandableMemUnit", ExpandableMemUnit);
                    cmd.Parameters.AddWithValue("@OSVersion", OSVersion);
                    cmd.Parameters.AddWithValue("@Processor", Processor);
                    cmd.Parameters.AddWithValue("@ScreenSize", ScreenSize);
                    cmd.Parameters.AddWithValue("@ScreenSizeType", ScreenSizeType);
                    cmd.Parameters.AddWithValue("@Battery", Battery);
                    cmd.Parameters.AddWithValue("@BatteryType", BatteryType);
                    cmd.Parameters.AddWithValue("@Comments", Comments);
                    cmd.Parameters.AddWithValue("@SupplierID", SupplierID);
                    cmd.Parameters.AddWithValue("@PurchasePrice", Price);
                    cmd.Parameters.AddWithValue("@PurchasePriceUnit", PriceUnit);
                    cmd.Parameters.AddWithValue("@UnitsInStock", UnitsInStock);
                    cmd.Parameters.AddWithValue("@ProductPhoto", SaveProductPhoto);
                    //Connection
                    conn.Open();
                    //Execution
                    cmd.ExecuteNonQuery();
                }
            }
        }
        public DataTable LoadCategoryComboBox()
        {
            DataTable categoryComboboxValues = new DataTable();

            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand cmd = new SqlCommand("spProducts_GetAllCategories", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    categoryComboboxValues.Load(reader);
                }
            }
            return categoryComboboxValues;
        }
        public DataTable LoadSeriesComboBox()
        {
            DataTable seriesComboBoxValues = new DataTable();

            using(SqlConnection conn = new SqlConnection(connString))
            {
                using(SqlCommand cmd = new SqlCommand("spProducts_GetAllSeries", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    seriesComboBoxValues.Load(reader);
                }
            }
            return seriesComboBoxValues;
        }
        public DataTable LoadSupplierComboBox()
        {
            DataTable supplierComboBoxValues = new DataTable();

            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand cmd = new SqlCommand("spProducts_GetAllSuppliers", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    supplierComboBoxValues.Load(reader);
                }
            }
            return supplierComboBoxValues;
        }
    }
}
</code>```

Stored procedure

```<code>ALTER Procedure [dbo].[spProducts_InsertProduct]
 @Name          nvarchar(50)
,@CategoryID    int
,@Model         nvarchar(50)
,@Series        nvarchar(50)
,@SIMSlots      int
,@CarrierType   nvarchar(20)
,@ReleaseDate   DateTime = null
,@RAM           int
,@RAMMemUnit    nvarchar(20)
,@SecondryMem   int
,@SecondMemUnit nvarchar(20)
,@Expandable    int
,@ExpandableMemUnit nvarchar(20)
,@OSVersion     nvarchar(50)
,@Processor     nvarchar(50)
,@ScreenSize    nvarchar(50)
,@ScreenSizeType nvarchar(20)
,@Battery       int
,@BatteryType   nvarchar(20)
,@Comments      nvarchar(MAX)
,@SupplierID    int
,@Price         float
,@PriceUnit     nvarchar(20)
,@UnitsInStock  int
,@ProductPhoto  IMAGE
As
Begin

INSERT INTO tblProducts(Name,CategoryID,Model,Series,SIMSlots,CarrierType,ReleaseDate,RAM,RAMMemUnit,SecondryMem,SecondMemUnit,Expandable,ExpandableMemUnit,OSVersion,Processor,ScreenSize,ScreenSizeType,Battery,BatteryType,Comments,SupplierID,Price,PriceUnit, UnitsInStock, Product_Photo)
VALUES(@Name,@CategoryID,@Model,@Series,@SIMSlots,@CarrierType,@ReleaseDate,@RAM,@RAMMemUnit,@SecondryMem,@SecondMemUnit,@Expandable,@ExpandableMemUnit,@OSVersion,@Processor,@ScreenSize,@ScreenSizeType,@Battery,@BatteryType,@Comments,@SupplierID,@Price,@PriceUnit,@UnitsInStock, @ProductPhoto)

End
</code>```

Help me please I'm stuck here from two days.
Thanks!

答:
This validation works if the text box is not empty

```<code>if (ExpandableTextBox.Text != "")
{
    int outexpmem;
    if (!int.TryParse(ExpandableTextBox.Text, out outexpmem))
    {
        ValidationMessage(ExpandableTextBox, "Expandable memory can only numbers!");
        return false;
    }
  if (ExpandableMemUnitComboBox.Text.Trim() == "")
    {
        ValidationMessage(ExpandableMemUnitComboBox, "Please select a Memory Unit!");
        return false;
    }
}
</code>```

But the line you're getting the error is trying to this Convert.ToInt32(ExpandableTextBox.Text) on every case.

If the ExpandableTextBox text is empty, this line will throw the error like you receive

```<code>db.InsertProductInDB(NameTextBox.Text, Convert.ToInt32(CategoryComboBox.SelectedValue), ModelTextBox.Text, SeriesComboBox.Text, Convert.ToInt32(SIMSlotsComboBox.Text), CarrierTypeComboBox.Text, GetReleaseDate(), Convert.ToInt32(RAMTextBox.Text), RAMMemUnitComboBox.Text, Convert.ToInt32(SecondryMemTextBox.Text), SecondMemUnitComboBox.Text, Convert.ToInt32(ExpandableTextBox.Text), ExpandableMemUnitComboBox.Text, OSVersionComboBox.Text, ProcessorComboBox.Text, ScreenSizeTextBox.Text, ScreenSizeTypeComboBox.Text, Convert.ToInt32(BatteryTextBox.Text), BatteryTypeComboBox.Text, CommentsTextBox.Text, Convert.ToInt32(SupplierComboBox.SelectedValue), float.Parse(PriceTextBox.Text), PriceUnitComboBox.Text, Convert.ToInt32(QuantityTextBox.Text), SaveProductPhoto());
</code>```

You can try something like this for optional fields Convert.ToInt32(!string.IsNullOrEmpty(ExpandableTextBox.Text)?ExpandableTextBox.Text :"0")

Body:
I'm trying to insert a form data into database but there is some problem with the code that I'm unable to identify it. The Error is:

An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll

  Additional information: Input string was not in a correct format.

Winform code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MobShopManagSys
{
    public partial class Product_AddForm : Form
    {
        ProductsDB db = new ProductsDB();
        public Product_AddForm()
        {
            InitializeComponent();
        }
        private void SaveButton_Click(object sender, EventArgs e)
        {
            if (IsValidated()) //Proceed if required data is entered
            {
                db.InsertProductInDB(NameTextBox.Text, Convert.ToInt32(CategoryComboBox.SelectedValue), ModelTextBox.Text, SeriesComboBox.Text, Convert.ToInt32(SIMSlotsComboBox.Text), CarrierTypeComboBox.Text, GetReleaseDate(), Convert.ToInt32(RAMTextBox.Text), RAMMemUnitComboBox.Text, Convert.ToInt32(SecondryMemTextBox.Text), SecondMemUnitComboBox.Text, Convert.ToInt32(ExpandableTextBox.Text), ExpandableMemUnitComboBox.Text, OSVersionComboBox.Text, ProcessorComboBox.Text, ScreenSizeTextBox.Text, ScreenSizeTypeComboBox.Text, Convert.ToInt32(BatteryTextBox.Text), BatteryTypeComboBox.Text, CommentsTextBox.Text, Convert.ToInt32(SupplierComboBox.SelectedValue), float.Parse(PriceTextBox.Text), PriceUnitComboBox.Text, Convert.ToInt32(QuantityTextBox.Text), SaveProductPhoto());
                MessageBox.Show("New Record is added successfully!", "Record Added", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void AddSupplierButton_Click(object sender, EventArgs e)
        {
            Suppliers_AddForm AddNewSupplierFrm = new Suppliers_AddForm();
            AddNewSupplierFrm.ShowDialog();
            //Reload Data into control
            LoadFormControlsData();

        }
        private void ResetButton_Click(object sender, EventArgs e)
        {
            NameTextBox.Clear();
            CategoryComboBox.Text = " ";
            ModelTextBox.Clear();
            SeriesComboBox.Text = null;
            CarrierTypeComboBox.Text = null;
            SIMSlotsComboBox.Text = null;
            ReleaseDateTimePicker.CustomFormat = " ";

            RAMTextBox.Clear();
            RAMMemUnitComboBox.Text = null;
            SecondryMemTextBox.Clear();
            SecondMemUnitComboBox.Text = null;
            ExpandableTextBox.Clear();
            ExpandableMemUnitComboBox.Text = null;

            OSVersionComboBox.Text = null;
            ProcessorComboBox.Text = null;
            ScreenSizeTextBox.Clear();
            ScreenSizeTypeComboBox.Text = null;
            BatteryTextBox.Clear();
            BatteryTypeComboBox.Text = null;

            CommentsTextBox.Clear();

            SupplierComboBox.Text = null;
            PriceTextBox.Clear();
            PriceUnitComboBox.Text = null;
            QuantityTextBox.Clear();

            SystemSounds.Beep.Play();
            NameTextBox.Focus();
        }
        private void Product_AddForm_Load(object sender, EventArgs e)
        {
            LoadFormControlsData();
        }

        private void LoadFormControlsData()
        {
            CategoryComboBox.DataSource = db.LoadCategoryComboBox();
            CategoryComboBox.DisplayMember = "CategoryName";
            CategoryComboBox.ValueMember = "CategoryID";
            CategoryComboBox.SelectedIndex = -1;

            SeriesComboBox.DataSource = db.LoadSeriesComboBox();
            SeriesComboBox.DisplayMember = "Series";

            SupplierComboBox.DataSource = db.LoadSupplierComboBox();
            SupplierComboBox.DisplayMember = "Name";
            SupplierComboBox.ValueMember = "SupplierID";
            SupplierComboBox.SelectedIndex = -1;
        }
        private void AddNewCategoryButton_Click(object sender, EventArgs e)
        {
            Categories_AddForm AddCategoryFrm = new Categories_AddForm();
            AddCategoryFrm.ShowDialog();

            LoadFormControlsData();
        }
        private void ProductImagePictureBox_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Select the Image";
            ofd.Filter = "Image File (*.png;*.jpg;*.bmp;*.gif)|*.png;*.jpg;*.bmp;*.gif";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                ProductImagePictureBox.Image = new Bitmap(ofd.FileName);
            }
        }
        private byte[] SaveProductPhoto()
        {
            MemoryStream ms = new MemoryStream();
            ProductImagePictureBox.Image.Save(ms, ProductImagePictureBox.Image.RawFormat);
            return ms.GetBuffer();
        }
    private bool IsValidated()  //Validation Method Defination
        {
            if (NameTextBox.Text.Trim() == "")
            {
                ValidationMessage(NameTextBox, "Name is required!");
                return false;
            }
            if (CategoryComboBox.Text.Trim() == "")
            {
                ValidationMessage(CategoryComboBox, "Please select the Category/Brand!");
                return false;
            }
            if (ModelTextBox.Text.Trim() == "")
            {
                ValidationMessage(ModelTextBox, "Model is required!");
                return false;
            }
            if (RAMTextBox.Text.Trim() == "")
            {
                ValidationMessage(RAMTextBox, "RAM memory required!");
                return false;
            }
            else
            {
                float outRAM;
                if(!float.TryParse(RAMTextBox.Text, out outRAM))
                {
                    ValidationMessage(RAMTextBox, "RAM field only contain numbers!");
                    return false;
                }
            }
            if (RAMMemUnitComboBox.Text.Trim() == "")
            {
                ValidationMessage(RAMMemUnitComboBox, "Please select a Memory Unit!");
                return false;
            }

            if (SecondryMemTextBox.Text.Trim() == "")
            {
                ValidationMessage(SecondryMemTextBox, "Secondry memory field is required!");
                return false;
            }
            else
            {
                float outSecMem;
                if (!float.TryParse(RAMTextBox.Text, out outSecMem))
                {
                    ValidationMessage(RAMTextBox, "Secondry memory field only contain numbers!");
                    return false;
                }
            }
            if (SecondMemUnitComboBox.Text.Trim() == "")
            {
                ValidationMessage(SecondMemUnitComboBox, "Please select a Memory Unit!");
                return false;
            }
            if (ExpandableTextBox.Text != "")
            {
                int outexpmem;
                if (!int.TryParse(ExpandableTextBox.Text, out outexpmem))
                {
                    ValidationMessage(ExpandableTextBox, "Expandable memory can only numbers!");
                    return false;
                }
              if (ExpandableMemUnitComboBox.Text.Trim() == "")
                {
                    ValidationMessage(ExpandableMemUnitComboBox, "Please select a Memory Unit!");
                    return false;
                }
            }
            if (OSVersionComboBox.Text.Trim() == "")
            {
                ValidationMessage(OSVersionComboBox, "OS Version selection is required!");
                return false;
            }
            if (BatteryTextBox.Text.Trim() == "")
            {
                ValidationMessage(BatteryTextBox, "Battery Capacity required!");
                return false;
            }
            if (BatteryTypeComboBox.Text.Trim() == "")
            {
                ValidationMessage(BatteryTypeComboBox, "Please select a Battery Capacity Unit!");
                return false;
            }
            if(PriceTextBox.Text != "" )
            {
                float outexpmem;
                if (!float.TryParse(PriceTextBox.Text, out outexpmem))
                {
                    ValidationMessage(PriceTextBox, "Purchase Price only numbers!");
                    return false;
                }
              if (PriceUnitComboBox.Text.Trim() == "")
                {
                    ValidationMessage(PriceUnitComboBox, "Please select Currency Unit!");
                    return false;
                }
            }

            if (QuantityTextBox.Text.Trim() == "")
            {
                ValidationMessage(QuantityTextBox, "Quantity of Product is required!");
                return false;
            }
            else
            {
                int outQuantity;
                if (!int.TryParse(QuantityTextBox.Text, out outQuantity))
                {
                    ValidationMessage(QuantityTextBox, "Quantity can only in numbers!");
                    return false;
                }
             }
            return true;
            }

        private void ValidationMessage(Control ctrl, string ValidationMsg) //Validation Message Def.
        {
            ctrl.BackColor = Color.LightPink;
            MessageBox.Show(ValidationMsg, "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            ctrl.Focus();
        }

        private void ctrl_TextChanged(object sender, EventArgs e) //Back change color to white
        {
            Control ctrl = (Control)sender;
            ctrl.BackColor = Color.White;
        }
        private void ClearCommentsButton_Click(object sender, EventArgs e)
        {
            CommentsTextBox.Clear();
            CommentsTextBox.Focus();
        }
        //Date Time Picker   <Start>
        private void ReleaseDateTimePicker_ValueChanged(object sender, EventArgs e)
        {
            ReleaseDateTimePicker.CustomFormat = "dd/MM/yyyy";
        }

        private void ReleaseDateTimePicker_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode==Keys.Back || e.KeyCode == Keys.Delete)
            {
                ReleaseDateTimePicker.CustomFormat = " ";
            }
        }
        private DateTime? GetReleaseDate()
        {
            if (ReleaseDateTimePicker.Text.Trim() == string.Empty)
            {
                return (DateTime?)null;
            }
            else
                return ReleaseDateTimePicker.Value.Date;
        }

    }  //Date Time Picker   <End>

}

Error in this line of code:

db.InsertProductInDB(NameTextBox.Text, Convert.ToInt32(CategoryComboBox.SelectedValue), ModelTextBox.Text, SeriesComboBox.Text, Convert.ToInt32(SIMSlotsComboBox.Text), CarrierTypeComboBox.Text, GetReleaseDate(), Convert.ToInt32(RAMTextBox.Text), RAMMemUnitComboBox.Text, Convert.ToInt32(SecondryMemTextBox.Text), SecondMemUnitComboBox.Text, Convert.ToInt32(ExpandableTextBox.Text), ExpandableMemUnitComboBox.Text, OSVersionComboBox.Text, ProcessorComboBox.Text, ScreenSizeTextBox.Text, ScreenSizeTypeComboBox.Text, Convert.ToInt32(BatteryTextBox.Text), BatteryTypeComboBox.Text, CommentsTextBox.Text, Convert.ToInt32(SupplierComboBox.SelectedValue), float.Parse(PriceTextBox.Text), PriceUnitComboBox.Text, Convert.ToInt32(QuantityTextBox.Text), SaveProductPhoto());

Database Class Code

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MobShopManagSys
{
    class ProductsDB
    {
        string connString = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;

        //Add Product Form
        public void InsertProductInDB(string Name, int CategoryID, string Model, string Series, int SIMSlots, string CarrierType, DateTime? ReleaseDate, int RAM, string RAMMemUnit, int SecondryMem, string SecondMemUnit, int Expandable, string ExpandableMemUnit, string OSVersion, string Processor, string ScreenSize, string ScreenSizeType, int Battery, string BatteryType, string Comments, int SupplierID, float Price, string PriceUnit, int UnitsInStock, byte[] SaveProductPhoto)
        {
            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand cmd = new SqlCommand("spProducts_InsertProduct", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    //Parameters
                    cmd.Parameters.AddWithValue("@Name", Name);
                    cmd.Parameters.AddWithValue("@CategoryID", CategoryID);
                    cmd.Parameters.AddWithValue("@Model", Model);
                    cmd.Parameters.AddWithValue("@Series", Series);
                    cmd.Parameters.AddWithValue("@SIMSlots", SIMSlots);
                    cmd.Parameters.AddWithValue("@CarrierType", CarrierType);
                    cmd.Parameters.AddWithValue("@ReleaseDate", ReleaseDate);
                    cmd.Parameters.AddWithValue("@RAM", RAM);
                    cmd.Parameters.AddWithValue("@RAMMemUnit", RAMMemUnit);
                    cmd.Parameters.AddWithValue("@SecondryMem", SecondryMem);
                    cmd.Parameters.AddWithValue("@SecondMemUnit", SecondMemUnit);
                    cmd.Parameters.AddWithValue("@Expandable", Expandable);
                    cmd.Parameters.AddWithValue("@ExpandableMemUnit", ExpandableMemUnit);
                    cmd.Parameters.AddWithValue("@OSVersion", OSVersion);
                    cmd.Parameters.AddWithValue("@Processor", Processor);
                    cmd.Parameters.AddWithValue("@ScreenSize", ScreenSize);
                    cmd.Parameters.AddWithValue("@ScreenSizeType", ScreenSizeType);
                    cmd.Parameters.AddWithValue("@Battery", Battery);
                    cmd.Parameters.AddWithValue("@BatteryType", BatteryType);
                    cmd.Parameters.AddWithValue("@Comments", Comments);
                    cmd.Parameters.AddWithValue("@SupplierID", SupplierID);
                    cmd.Parameters.AddWithValue("@PurchasePrice", Price);
                    cmd.Parameters.AddWithValue("@PurchasePriceUnit", PriceUnit);
                    cmd.Parameters.AddWithValue("@UnitsInStock", UnitsInStock);
                    cmd.Parameters.AddWithValue("@ProductPhoto", SaveProductPhoto);
                    //Connection
                    conn.Open();
                    //Execution
                    cmd.ExecuteNonQuery();
                }
            }
        }
        public DataTable LoadCategoryComboBox()
        {
            DataTable categoryComboboxValues = new DataTable();

            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand cmd = new SqlCommand("spProducts_GetAllCategories", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    categoryComboboxValues.Load(reader);
                }
            }
            return categoryComboboxValues;
        }
        public DataTable LoadSeriesComboBox()
        {
            DataTable seriesComboBoxValues = new DataTable();

            using(SqlConnection conn = new SqlConnection(connString))
            {
                using(SqlCommand cmd = new SqlCommand("spProducts_GetAllSeries", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    seriesComboBoxValues.Load(reader);
                }
            }
            return seriesComboBoxValues;
        }
        public DataTable LoadSupplierComboBox()
        {
            DataTable supplierComboBoxValues = new DataTable();

            using (SqlConnection conn = new SqlConnection(connString))
            {
                using (SqlCommand cmd = new SqlCommand("spProducts_GetAllSuppliers", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    conn.Open();
                    SqlDataReader reader = cmd.ExecuteReader();
                    supplierComboBoxValues.Load(reader);
                }
            }
            return supplierComboBoxValues;
        }
    }
}

Stored procedure

ALTER Procedure [dbo].[spProducts_InsertProduct]
 @Name          nvarchar(50)
,@CategoryID    int
,@Model         nvarchar(50)
,@Series        nvarchar(50)
,@SIMSlots      int
,@CarrierType   nvarchar(20)
,@ReleaseDate   DateTime = null
,@RAM           int
,@RAMMemUnit    nvarchar(20)
,@SecondryMem   int
,@SecondMemUnit nvarchar(20)
,@Expandable    int
,@ExpandableMemUnit nvarchar(20)
,@OSVersion     nvarchar(50)
,@Processor     nvarchar(50)
,@ScreenSize    nvarchar(50)
,@ScreenSizeType nvarchar(20)
,@Battery       int
,@BatteryType   nvarchar(20)
,@Comments      nvarchar(MAX)
,@SupplierID    int
,@Price         float
,@PriceUnit     nvarchar(20)
,@UnitsInStock  int
,@ProductPhoto  IMAGE
As
Begin

INSERT INTO tblProducts(Name,CategoryID,Model,Series,SIMSlots,CarrierType,ReleaseDate,RAM,RAMMemUnit,SecondryMem,SecondMemUnit,Expandable,ExpandableMemUnit,OSVersion,Processor,ScreenSize,ScreenSizeType,Battery,BatteryType,Comments,SupplierID,Price,PriceUnit, UnitsInStock, Product_Photo)
VALUES(@Name,@CategoryID,@Model,@Series,@SIMSlots,@CarrierType,@ReleaseDate,@RAM,@RAMMemUnit,@SecondryMem,@SecondMemUnit,@Expandable,@ExpandableMemUnit,@OSVersion,@Processor,@ScreenSize,@ScreenSizeType,@Battery,@BatteryType,@Comments,@SupplierID,@Price,@PriceUnit,@UnitsInStock, @ProductPhoto)

End

Help me please I'm stuck here from two days.
Thanks!

Body:
This validation works if the text box is not empty

if (ExpandableTextBox.Text != "")
{
    int outexpmem;
    if (!int.TryParse(ExpandableTextBox.Text, out outexpmem))
    {
        ValidationMessage(ExpandableTextBox, "Expandable memory can only numbers!");
        return false;
    }
  if (ExpandableMemUnitComboBox.Text.Trim() == "")
    {
        ValidationMessage(ExpandableMemUnitComboBox, "Please select a Memory Unit!");
        return false;
    }
}

But the line you're getting the error is trying to this Convert.ToInt32(ExpandableTextBox.Text) on every case.

If the ExpandableTextBox text is empty, this line will throw the error like you receive

db.InsertProductInDB(NameTextBox.Text, Convert.ToInt32(CategoryComboBox.SelectedValue), ModelTextBox.Text, SeriesComboBox.Text, Convert.ToInt32(SIMSlotsComboBox.Text), CarrierTypeComboBox.Text, GetReleaseDate(), Convert.ToInt32(RAMTextBox.Text), RAMMemUnitComboBox.Text, Convert.ToInt32(SecondryMemTextBox.Text), SecondMemUnitComboBox.Text, Convert.ToInt32(ExpandableTextBox.Text), ExpandableMemUnitComboBox.Text, OSVersionComboBox.Text, ProcessorComboBox.Text, ScreenSizeTextBox.Text, ScreenSizeTypeComboBox.Text, Convert.ToInt32(BatteryTextBox.Text), BatteryTypeComboBox.Text, CommentsTextBox.Text, Convert.ToInt32(SupplierComboBox.SelectedValue), float.Parse(PriceTextBox.Text), PriceUnitComboBox.Text, Convert.ToInt32(QuantityTextBox.Text), SaveProductPhoto());

You can try something like this for optional fields Convert.ToInt32(!string.IsNullOrEmpty(ExpandableTextBox.Text)?ExpandableTextBox.Text :"0")


来源: stackexchange

问:
In React, how to convert country code to country name, using country-data?
Using country-data, I thought I could do

```<code>npm install --save country-data
</code>```

and then in the code:

```<code>import CountryData from "country-data";
</code>```

and use

```<code>CountryData.countries["TW"]
</code>```

to get the country data, and

```<code>CountryData.countries["TW"].name
</code>```

to get the name. But CountryData.countries["TW"] gets undefined already. How can it be done? Are there possible better alternatives to using country-data?

P.S. the npm page and github page of country-data has some info on how to use it with webpack, which I suspect is needed to be used with React. But I did them:

```<code>npm install json-loader --save-dev
</code>```

add to webpack.config.js:

```<code>// ...
   loaders: [
      // other loaders
      { test: /\.json$/, loader: 'json' },
  ],
// ...
</code>```

and it doessn't work yet.

答:
It seems you are using the npm module incorrectly

According to the docs you can do it as follows

```<code>npm install --save country-data
</code>```

And import it like

```<code>import {countries} from 'country-data';
</code>```

and then use it like

```<code>console.log(countries["TW"].name);
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Using country-data, I thought I could do

npm install --save country-data

and then in the code:

import CountryData from "country-data";

and use

CountryData.countries["TW"]

to get the country data, and

CountryData.countries["TW"].name

to get the name. But CountryData.countries["TW"] gets undefined already. How can it be done? Are there possible better alternatives to using country-data?

P.S. the npm page and github page of country-data has some info on how to use it with webpack, which I suspect is needed to be used with React. But I did them:

npm install json-loader --save-dev

add to webpack.config.js:

// ...
   loaders: [
      // other loaders
      { test: /\.json$/, loader: 'json' },
  ],
// ...

and it doessn't work yet.

Body:
It seems you are using the npm module incorrectly

According to the docs you can do it as follows

npm install --save country-data

And import it like

import {countries} from 'country-data';

and then use it like

console.log(countries["TW"].name);


问:
NullPointerException when using UDF in Spark
I have a DataFrame in Spark such as this one:

```<code>var df = List(
  (1,"{NUM.0002}*{NUM.0003}"),
  (2,"{NUM.0004}+{NUM.0003}"),
  (3,"END(6)"),
  (4,"END(4)")
).toDF("CODE", "VALUE")

+----+---------------------+
|CODE|                VALUE|
+----+---------------------+
|   1|{NUM.0002}*{NUM.0003}|
|   2|{NUM.0004}+{NUM.0003}|
|   3|               END(6)|
|   4|               END(4)|
+----+---------------------+
</code>```

My task is to iterate through the VALUE column and do the following: check if there is a substring such as {NUM.XXXX}, get the XXXX number, get the row where $"CODE" === XXXX, and replace the {NUM.XXX} substring with the VALUE string in that row.

I would like the dataframe to look like this in the end:

```<code>+----+--------------------+
|CODE|               VALUE|
+----+--------------------+
|   1|END(4)+END(6)*END(6)|
|   2|       END(4)+END(6)|
|   3|              END(6)|
|   4|              END(4)|
+----+--------------------+
</code>```

This is the best I've come up with:

```<code>val process = udf((ln: String) => {
  var newln = ln
  while(newln contains "{NUM."){
    var num = newln.slice(newln.indexOf("{")+5, newln.indexOf("}")).toInt
    var new_value = df.where($"CODE" === num).head.getAs[String](1)
    newln = newln.replace(newln.slice(newln.indexOf("{"),newln.indexOf("}")+1), new_value)
  }
  newln
})

var df2 = df.withColumn("VALUE", when('VALUE contains "{NUM.",process('VALUE)).otherwise('VALUE))
</code>```

Unfortunately, I get a NullPointerException when I try to filter/select/save df2, and no error when I just show df2. I believe the error appears when I access the DataFrame df within the UDF, but I need to access it every iteration, so I can't pass it as an input. Also, I've tried saving a copy of df inside the UDF but I don't know how to do that. What can I do here?

Any suggestions to improve the algorithm are very welcome! Thanks!

答:
I wrote something which works but not very optimized I think. I actually do recursive joins on the initial DataFrame to replace the NUMs by END. Here is the code :

```<code>    case class Data(code: Long, value: String)

    def main(args: Array[String]): Unit = {
        val sparkSession: SparkSession = SparkSession.builder().master("local").getOrCreate()

        val data = Seq(
            Data(1,"{NUM.0002}*{NUM.0003}"),
            Data(2,"{NUM.0004}+{NUM.0003}"),
            Data(3,"END(6)"),
            Data(4,"END(4)"),
            Data(5,"{NUM.0002}")
        )

        val initialDF = sparkSession.createDataFrame(data)
        val endDF = initialDF.filter(!(col("value") contains "{NUM"))
        val numDF = initialDF.filter(col("value") contains "{NUM")

        val resultDF = endDF.union(replaceNumByEnd(initialDF, numDF))
        resultDF.show(false)
    }

    val parseNumUdf = udf((value: String) => {
        if (value.contains("{NUM")) {
            val regex = """.*?\{NUM\.(\d+)\}.*""".r
            value match {
                case regex(code) => code.toLong
            }
        } else {
            -1L
        }
    })

    val replaceUdf = udf((value: String, replacement: String) => {
        val regex = """\{NUM\.(\d+)\}""".r
        regex.replaceFirstIn(value, replacement)
    })

    def replaceNumByEnd(initialDF: DataFrame, currentDF: DataFrame): DataFrame = {
        if (currentDF.count() == 0) {
            currentDF
        } else {
            val numDFWithCode = currentDF
                .withColumn("num_code", parseNumUdf(col("value")))
                .withColumnRenamed("code", "code_original")
                .withColumnRenamed("value", "value_original")

            val joinedDF = numDFWithCode.join(initialDF, numDFWithCode("num_code") === initialDF("code"))

            val replacedDF = joinedDF.withColumn("value_replaced", replaceUdf(col("value_original"), col("value")))

            val nextDF = replacedDF.select(col("code_original").as("code"), col("value_replaced").as("value"))

            val endDF = nextDF.filter(!(col("value") contains "{NUM"))
            val numDF = nextDF.filter(col("value") contains "{NUM")

            endDF.union(replaceNumByEnd(initialDF, numDF))
        }
    }
</code>```

If you need more explanation, don't hesitate.

Body:
I have a DataFrame in Spark such as this one:

var df = List(
  (1,"{NUM.0002}*{NUM.0003}"),
  (2,"{NUM.0004}+{NUM.0003}"),
  (3,"END(6)"),
  (4,"END(4)")
).toDF("CODE", "VALUE")

+----+---------------------+
|CODE|                VALUE|
+----+---------------------+
|   1|{NUM.0002}*{NUM.0003}|
|   2|{NUM.0004}+{NUM.0003}|
|   3|               END(6)|
|   4|               END(4)|
+----+---------------------+

My task is to iterate through the VALUE column and do the following: check if there is a substring such as {NUM.XXXX}, get the XXXX number, get the row where $"CODE" === XXXX, and replace the {NUM.XXX} substring with the VALUE string in that row.

I would like the dataframe to look like this in the end:

+----+--------------------+
|CODE|               VALUE|
+----+--------------------+
|   1|END(4)+END(6)*END(6)|
|   2|       END(4)+END(6)|
|   3|              END(6)|
|   4|              END(4)|
+----+--------------------+

This is the best I've come up with:

val process = udf((ln: String) => {
  var newln = ln
  while(newln contains "{NUM."){
    var num = newln.slice(newln.indexOf("{")+5, newln.indexOf("}")).toInt
    var new_value = df.where($"CODE" === num).head.getAs[String](1)
    newln = newln.replace(newln.slice(newln.indexOf("{"),newln.indexOf("}")+1), new_value)
  }
  newln
})

var df2 = df.withColumn("VALUE", when('VALUE contains "{NUM.",process('VALUE)).otherwise('VALUE))

Unfortunately, I get a NullPointerException when I try to filter/select/save df2, and no error when I just show df2. I believe the error appears when I access the DataFrame df within the UDF, but I need to access it every iteration, so I can't pass it as an input. Also, I've tried saving a copy of df inside the UDF but I don't know how to do that. What can I do here?

Any suggestions to improve the algorithm are very welcome! Thanks!

Body:
I wrote something which works but not very optimized I think. I actually do recursive joins on the initial DataFrame to replace the NUMs by END. Here is the code :

    case class Data(code: Long, value: String)

    def main(args: Array[String]): Unit = {
        val sparkSession: SparkSession = SparkSession.builder().master("local").getOrCreate()

        val data = Seq(
            Data(1,"{NUM.0002}*{NUM.0003}"),
            Data(2,"{NUM.0004}+{NUM.0003}"),
            Data(3,"END(6)"),
            Data(4,"END(4)"),
            Data(5,"{NUM.0002}")
        )

        val initialDF = sparkSession.createDataFrame(data)
        val endDF = initialDF.filter(!(col("value") contains "{NUM"))
        val numDF = initialDF.filter(col("value") contains "{NUM")

        val resultDF = endDF.union(replaceNumByEnd(initialDF, numDF))
        resultDF.show(false)
    }

    val parseNumUdf = udf((value: String) => {
        if (value.contains("{NUM")) {
            val regex = """.*?\{NUM\.(\d+)\}.*""".r
            value match {
                case regex(code) => code.toLong
            }
        } else {
            -1L
        }
    })

    val replaceUdf = udf((value: String, replacement: String) => {
        val regex = """\{NUM\.(\d+)\}""".r
        regex.replaceFirstIn(value, replacement)
    })

    def replaceNumByEnd(initialDF: DataFrame, currentDF: DataFrame): DataFrame = {
        if (currentDF.count() == 0) {
            currentDF
        } else {
            val numDFWithCode = currentDF
                .withColumn("num_code", parseNumUdf(col("value")))
                .withColumnRenamed("code", "code_original")
                .withColumnRenamed("value", "value_original")

            val joinedDF = numDFWithCode.join(initialDF, numDFWithCode("num_code") === initialDF("code"))

            val replacedDF = joinedDF.withColumn("value_replaced", replaceUdf(col("value_original"), col("value")))

            val nextDF = replacedDF.select(col("code_original").as("code"), col("value_replaced").as("value"))

            val endDF = nextDF.filter(!(col("value") contains "{NUM"))
            val numDF = nextDF.filter(col("value") contains "{NUM")

            endDF.union(replaceNumByEnd(initialDF, numDF))
        }
    }

If you need more explanation, don't hesitate.


问:
Calculating an Avg in SQL excluding the current row
I have a DB where certain records are tagged with an ID and I want create a view that contains the Average of all those records with the same ID, EXCLUDING the current record.  For example, if my data looks like this:

```<code>ROW - ID - Value
1     1    20
2     1    30
3     1    40
4     2    60
5     2    80
6     2    40
7     3    50
8     3    20
9     3    40
</code>```

My view needs to calculate the average of every row with the same ID, EXCLUDING the row it's on, so my output would look something like this:

```<code>ROW - ID - Value AVG
1     1    20    35
2     1    30    30
3     1    40    25
4     2    60    60
5     2    80    50
6     2    40    70
7     3    50    30
8     3    20    55
9     3    40    35
</code>```

So, in the case of row 3, it's extracted rows 1 and 2, as they have the same ID and given me the avg of their values - 25.

I'm gone round the houses on this for a while now, but can't seem to nail it.  Any help would be appreciated.

答:
One Option if you have window functions

```<code>Declare @YourTable table (ROW int,ID int,Value int)
Insert Into @YourTable values
(1,     1,    20),
(2,     1,    30),
(3,     1,    40),
(4,     2,    60),
(5,     2,    80),
(6,     2,    40),
(7,     3,    50),
(8,     3,    20),
(9,     3,    40)

Select *
      ,Avg = (sum(value) over (Partition By ID)-Value)/NullIf((sum(1) over (Partition By ID)-1),0)
 From  @YourTable
</code>```

Another Option is a OUTER APPLY

```<code>Select A.*
      ,B.*
 From  @YourTable A
 Outer Apply (Select Avg=avg(value)
               From  @YourTable
               where ID=A.ID and Row<>A.Row
              ) B
</code>```

Both Return

Body:
I have a DB where certain records are tagged with an ID and I want create a view that contains the Average of all those records with the same ID, EXCLUDING the current record.  For example, if my data looks like this:

ROW - ID - Value
1     1    20
2     1    30
3     1    40
4     2    60
5     2    80
6     2    40
7     3    50
8     3    20
9     3    40

My view needs to calculate the average of every row with the same ID, EXCLUDING the row it's on, so my output would look something like this:

ROW - ID - Value AVG
1     1    20    35
2     1    30    30
3     1    40    25
4     2    60    60
5     2    80    50
6     2    40    70
7     3    50    30
8     3    20    55
9     3    40    35

So, in the case of row 3, it's extracted rows 1 and 2, as they have the same ID and given me the avg of their values - 25.

I'm gone round the houses on this for a while now, but can't seem to nail it.  Any help would be appreciated.

Body:
One Option if you have window functions

Declare @YourTable table (ROW int,ID int,Value int)
Insert Into @YourTable values
(1,     1,    20),
(2,     1,    30),
(3,     1,    40),
(4,     2,    60),
(5,     2,    80),
(6,     2,    40),
(7,     3,    50),
(8,     3,    20),
(9,     3,    40)

Select *
      ,Avg = (sum(value) over (Partition By ID)-Value)/NullIf((sum(1) over (Partition By ID)-1),0)
 From  @YourTable

Another Option is a OUTER APPLY

Select A.*
      ,B.*
 From  @YourTable A
 Outer Apply (Select Avg=avg(value)
               From  @YourTable
               where ID=A.ID and Row<>A.Row
              ) B

Both Return


问:
Application.ThreadException is getting incorrect Win32Exception type
We have a very large complicated application that has a ThreadException handler intialized at startup, and any exceptions thrown by the application that are not handled immediately are handled by this ThreadException handler in a unified way.

This mostly works...but we have a couple custom exception types that we want to handle with this exception handler, and for some reason these exception types always show up in the ThreadException handler as just System.ComponentModel.Win32Exception types, instead of our custom types.

I've tried anything I can think of to troubleshoot, including making sure our custom exception classes implement all recommended constructors, including a serialiation constructor.

Additional info...when I create a new exception with just the message from the existing exception, this comes through as a System.Exception.  For example:

```<code>                MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
                throw new Exception(ex.Message);
</code>```

works fine and is caught in the exception handler as a System.Exception.

However, if I try something like:

```<code>                MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
                throw new Exception(ex.Message, ex);
</code>```

Then the exception manager catches the above System.ComponentModel.Win32Exception instead of just a System.Exception.

Just for completeness, what I WANT to do is something like:

```<code>                throw new MSCSqlException(sqlQuery, sqlParams, sqlException);
</code>```

and have the Application.ThreadException handler receive a properly typed MSCSqlException.

Any ideas how to get around this?  Is there some quirk of Application.ThreadException that I'm missing related to custom error types?

Our custom exception class:

```<code>[Serializable]
public class MSCSqlException : Exception
{
    public string SqlCommand { get; private set; }
    public object[] SqlParameters { get; private set; }

    public MSCSqlException()
    {
    }

    public MSCSqlException(string message)
        : base(message)
    {
    }

    public MSCSqlException(string message, Exception inner) : base(message, inner)
    {
    }

    public MSCSqlException(string command, object[] parameters, SqlException sx) : base(CreateUsefulMessage(sx, command, parameters), sx)
    {
        SqlCommand = command;
        SqlParameters = parameters;
    }

    protected MSCSqlException(SerializationInfo info, StreamingContext context) : base(info, context)
    {
        SqlCommand = info.GetString("SqlCommand");
    }

    [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
        {
            throw new ArgumentNullException("info");
        }

        info.AddValue("SqlCommand", SqlCommand);
        base.GetObjectData(info, context);
    }

    public static string CreateUsefulMessage(SqlException sx, string sqlCommand, object[] sqlParameters)
    {
        string message = sx.Message + Environment.NewLine;

        if(sqlParameters != null && sqlParameters.Count() > 0)
        {
            message = message + "Parameters:" + Environment.NewLine;
            foreach(object sp in sqlParameters)
            {
                message = message + "\t" + sp.ToString() + Environment.NewLine;
            }
        }

        message = message + "SQL Statement:" + Environment.NewLine;
        message = message + sqlCommand;

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

答:
We finally figured this out...the issue is a bug or feature in how .Net handles exceptions thrown in a background worker Completed event.  For whatever reason, it appears that in this case, the .Net run time is passing the innermost exception from the stack trace to the ThreadException handler instead of the expected outermost exception.  This innermost exception when a SQLException is thrown is a Win32Exception.

More info on this here:

Application.ThreadException is getting incorrect Win32Exception type

Body:
We have a very large complicated application that has a ThreadException handler intialized at startup, and any exceptions thrown by the application that are not handled immediately are handled by this ThreadException handler in a unified way.

This mostly works...but we have a couple custom exception types that we want to handle with this exception handler, and for some reason these exception types always show up in the ThreadException handler as just System.ComponentModel.Win32Exception types, instead of our custom types.

I've tried anything I can think of to troubleshoot, including making sure our custom exception classes implement all recommended constructors, including a serialiation constructor.

Additional info...when I create a new exception with just the message from the existing exception, this comes through as a System.Exception.  For example:

                MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
                throw new Exception(ex.Message);

works fine and is caught in the exception handler as a System.Exception.

However, if I try something like:

                MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
                throw new Exception(ex.Message, ex);

Then the exception manager catches the above System.ComponentModel.Win32Exception instead of just a System.Exception.

Just for completeness, what I WANT to do is something like:

                throw new MSCSqlException(sqlQuery, sqlParams, sqlException);

and have the Application.ThreadException handler receive a properly typed MSCSqlException.

Any ideas how to get around this?  Is there some quirk of Application.ThreadException that I'm missing related to custom error types?

Our custom exception class:

[Serializable]
public class MSCSqlException : Exception
{
    public string SqlCommand { get; private set; }
    public object[] SqlParameters { get; private set; }

    public MSCSqlException()
    {
    }

    public MSCSqlException(string message)
        : base(message)
    {
    }

    public MSCSqlException(string message, Exception inner) : base(message, inner)
    {
    }

    public MSCSqlException(string command, object[] parameters, SqlException sx) : base(CreateUsefulMessage(sx, command, parameters), sx)
    {
        SqlCommand = command;
        SqlParameters = parameters;
    }

    protected MSCSqlException(SerializationInfo info, StreamingContext context) : base(info, context)
    {
        SqlCommand = info.GetString("SqlCommand");
    }

    [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
        {
            throw new ArgumentNullException("info");
        }

        info.AddValue("SqlCommand", SqlCommand);
        base.GetObjectData(info, context);
    }

    public static string CreateUsefulMessage(SqlException sx, string sqlCommand, object[] sqlParameters)
    {
        string message = sx.Message + Environment.NewLine;

        if(sqlParameters != null && sqlParameters.Count() > 0)
        {
            message = message + "Parameters:" + Environment.NewLine;
            foreach(object sp in sqlParameters)
            {
                message = message + "\t" + sp.ToString() + Environment.NewLine;
            }
        }

        message = message + "SQL Statement:" + Environment.NewLine;
        message = message + sqlCommand;

        return message;
    }
}


问:
frontend backend class exchange
I'm writing application using Angular2 and PHP (REST API mostly). The problem is that I have almost the same classes for angular and for php. For example in php I have a class Contract with some fields like title, description, provider. Also I have api endpoint getContract() to return all these fields. And I have the same class in angular, so I can add some logic here like getters and setters. That's really annoying me to write 2 similar classes each time, and if I need to change something, I have to change it twice. But now I have a new requirement, to create separated project with API, so in two words now I have to create 3 classes each time.

So, if the problem is clear, I want to talk about possible solutions, after google some time I didn't find anything, for now I'm on the first step and hope someone can turn me in the right direction. What's the best practices there? May be store classes in json, and then parse in with angular and php? Thanks for any advices

答:
Some repetitive feeling code isn't repetition in the DRY sense.

In other words, if you have to spend 10 extra minutes on each model, duplicating fields from one class with one responsibility to another class, potentially in a different language, with another responsibility, that's pretty standard. It's OK. And, it is not vain repetition.

Your front-end classes and your backend classes might be damn-near identical; but, they do different things. The fact that they share fields is almost coincidental, and it's not guaranteed. In some applications, the client and server models can diverge quite a bit.

And, it's worth noting, in many frameworks, the repetition is even worse than you think! If you separate your server model in a domain and DTO's, you could easily have 2 to 4 "pretty darn identical" server models. And, some MVC client framework result in similar duplicative code. (Or, didn't you realize your templates are yet another enumeration of the models in a drastically different syntax?)

... In the end, a really robust application might end up having 4 to 6 or more translations of your underlying models.

Automatic model/code generation isn't free.

Suppose all of your corresponding front-end and back-end classes are basically "identical." It will certainly feel silly spending 5 minutes copying fields from one syntax to another, but your colleagues will think you're a whole lot sillier if you end up spending a month banging out a solution to save an hour per project.

You'll also feel pretty frustrated when your solution breaks and you end up spending an additional hour or two "every now and then" when the code generator does unexpected things.

Even if you find an off-the-shelf solution that you only have install, there's time invested in that. There's a learning curve. There will be maintenance. A there will be unexpected issues.

You might save time in the long long run; but, you need to do that math

That said, there are options.

You could find a transpiler. Like this one, or this one, or this one, etc. ...

You could load the base models in your JS/PHP from JSON, XML, or any format you like and append your logic.

You could generate your base JS/PHP from JSON, XML, or any format you like.

You could generate your base client models on the fly. I.e., just use the server response as your base model and append client methods to it.

You could generate your base server models on the fly. I.e., your server acts like dumb storage when possible. Maybe it knows about who owns what ... but not much more. (Just make sure the server models are "smart" for objects passed between users.)

You could make a case for switching to nodejs!

And maybe you'll sleep better at night spending extra time to avoid repetition of any kind. Maybe you'll feel like your test suite doesn't need to be as big. Or whatever.

If that's the case, go for it.

But, the repetition you're referring to isn't necessarily in vain or abnormal. The client models and the server models should be doing different things, even if they look and feel like vain restatements of each other.

Title: frontend backend class exchange


问:
How to do aggregation (AVG, SUM, MAX etc.) on Azure DocumentDB?
I am trying out Azure DocumentDB and their documentation says aggregation is supported. Indeed, I am able to do COUNT by:

```<code>SELECT value COUNT(1) FROM c WHERE c.id = 'someid'
</code>```

However, if I follow same syntax to do other types of aggregation, it doesn't seem to work.

```<code>SELECT value MAX(value) FROM c WHERE c.id = 'someid'
</code>```

gives error. This is same with MIN.

It looks like aggregation is not supported (even though docs says otherwise). Or is there different approach to do it?

答:
For MAX() to work, you need to aggregate on a given property. For example, if you had a few documents with a range property:

```<code>{
  "id": "max1",
  "range": 50
}
{
  "id": "max2",
  "range": 20
}
</code>```

You'd get the max value of range via:

```<code>SELECT MAX(c.range) from c
</code>```

Which returns:

```<code>[
  {
    "$1": 50
  }
]
</code>```

Or

```<code>SELECT VALUE MAX(c.range) from c
</code>```

Which returns:

```<code>[
  50
]
</code>```

Note: In your question's example, you use c.value. VALUE is a reserved word, so you'd need to reference as c['value']. For example:

```<code>SELECT VALUE MAX(c['value']) from c
</code>```

Body:
I am trying out Azure DocumentDB and their documentation says aggregation is supported. Indeed, I am able to do COUNT by:

SELECT value COUNT(1) FROM c WHERE c.id = 'someid'

However, if I follow same syntax to do other types of aggregation, it doesn't seem to work.

SELECT value MAX(value) FROM c WHERE c.id = 'someid'

gives error. This is same with MIN.

It looks like aggregation is not supported (even though docs says otherwise). Or is there different approach to do it?

Body:
For MAX() to work, you need to aggregate on a given property. For example, if you had a few documents with a range property:

{
  "id": "max1",
  "range": 50
}
{
  "id": "max2",
  "range": 20
}

You'd get the max value of range via:

SELECT MAX(c.range) from c

Which returns:

[
  {
    "$1": 50
  }
]

Or

SELECT VALUE MAX(c.range) from c

Which returns:

[
  50
]

Note: In your question's example, you use c.value. VALUE is a reserved word, so you'd need to reference as c['value']. For example:

SELECT VALUE MAX(c['value']) from c


问:
QT how to emit a signal in this case
I need to develop a Sudoku game. After reading a text file containing the number values, I create 9*9 widgets.
If (the value is already set then I instantiate to a qlabel containing the number,
else I instantiate a combobox containing the possible values of each case).

Until here everything is OK.
The problem is that when a value is chosen from the combobox, I need to draw it in a square in my view (MVC).  The problem is how can I know which one was chosen?

The only signal can I use from combobox signals is currenttextchanged(QString), but I'll not know which combo made that signal.
The ideal for me would be something like this SIGNAL(curretextchanged(QString, int, int)), but I don't know if I can define a new signal?

Here is some code:

```<code>QWidget *tab[9][9];
SudModel *modele = ???;
QComboBox *combobox = new QComboBox();
combobox->setStyleSheet("border: 1px solid red");
int tmp = modele->valuesof(i, j).size();

for (int s = 0; s < tmp; s++) {
    combobox->addItem(QString::number(modele->valuesof(i, j)[s]));
}

connect(combobox, SIGNAL(currentTextChanged(QString)), this, SLOT(update()));
tab[i][j] = combobox;
</code>```

答:
One solution would be to attach that extra information when you connect to the signal for a specific combobox.

For example, say you have your function update(QString text, int x, int y) then you could attach the signal to a lambda that calls the function with the extra arguments, captured at connect time. Something like this:

```<code>connect(combobox, &QComboBox::currentTextChanged, [x, y, this](const QString& text){ this->update(text, x, y); });
</code>```

That would then call the update functions with the x and y values captured when the connection was made along with the text argument that originated from the signal.

Title: QT how to emit a signal in this case

Body:
I need to develop a Sudoku game. After reading a text file containing the number values, I create 9*9 widgets.
If (the value is already set then I instantiate to a qlabel containing the number,
else I instantiate a combobox containing the possible values of each case).

Until here everything is OK.
The problem is that when a value is chosen from the combobox, I need to draw it in a square in my view (MVC).  The problem is how can I know which one was chosen?

The only signal can I use from combobox signals is currenttextchanged(QString), but I'll not know which combo made that signal.
The ideal for me would be something like this SIGNAL(curretextchanged(QString, int, int)), but I don't know if I can define a new signal?

Here is some code:

QWidget *tab[9][9];
SudModel *modele = ???;
QComboBox *combobox = new QComboBox();
combobox->setStyleSheet("border: 1px solid red");
int tmp = modele->valuesof(i, j).size();

for (int s = 0; s < tmp; s++) {
    combobox->addItem(QString::number(modele->valuesof(i, j)[s]));
}

connect(combobox, SIGNAL(currentTextChanged(QString)), this, SLOT(update()));
tab[i][j] = combobox;

Body:
One solution would be to attach that extra information when you connect to the signal for a specific combobox.

For example, say you have your function update(QString text, int x, int y) then you could attach the signal to a lambda that calls the function with the extra arguments, captured at connect time. Something like this:

connect(combobox, &QComboBox::currentTextChanged, [x, y, this](const QString& text){ this->update(text, x, y); });

That would then call the update functions with the x and y values captured when the connection was made along with the text argument that originated from the signal.


问:
Creating a password scrambler
I'm trying to copy a password scrambler from Javascript to C. What it does is take the ASCII character code of the letter, floor it, divide it, and grab a random character out of a given list.

Javascript version:

```<code>function getScrambledPassword(pwd) {
    var cipher = ['k', 's', 'z', 'h', 'x', 'b', 'p', 'j', 'v', 'c', 'g', 'f', 'q', 'n', 't', 'm'];
    var result="";
    if (pwd == null)
        pwd = "";
    pwd = encodeURIComponent(pwd);
    //alert("encoded password: " + pwd);
    for(var i=0;i<pwd.length;i++) {
            var cc = pwd.charCodeAt(i);
        result += cipher[Math.floor(cc/16)] + cipher[cc%16];
    }
    //alert("scrambled password: " + result);
    return result;
}
</code>```

Example of the scrambler being run: https://jsfiddle.net/w5db66va/

What I've done so far:

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

static char *scramblePassword(char *pwd)
{
    char *cipher[] = {
        "k", "s", "z", "h",
        "x", "b", "p", "j",
        "v", "c", "g", "f",
        "q", "n", "t", "m"
    };

    char *result = "";
    for(int i=0; i < strlen(pwd); i++)
    {
        int cc = (int) pwd[i];
        printf("%d", cc);
        result + cipher[floor(cc/16)] + cipher[cc%16];
    }
    return *result;
}

int main(void)
{
    char *test[] = {"test", "testtwo", "testthree"};
    for (int i=0;i < sizeof(test); i++)
    {
        printf("Original: %s", test[i]);
        printf("Scrambled: %s", scramblePassword(test[i]));
    }
}
</code>```

The issue I'm experiencing is that when I run the c file (after compilation) it will not output anything at all. What am I doing wrong to the point that I cannot get this to run as I'd expect it?

答:
Continuing from the comment, your problems run a bit deeper than you may first think. To begin, you do not want cipher to be an array of strings, you simply want it to be a character array, e.g.:

```<code>    char cipher[] = "kszhxbpjvcgfqnm";
</code>```

Next, you cannot return an array that is declared within the body of a function. The memory for result is destroyed when scramblePassword returns. Your choices are (1) dynamically allocate result in scramblePassword (and free it in main), or (2) declare storage for result in main and pass it as a parameter to scramblePassword. e.g.:

```<code>#define MAX 32

static char *scramblePassword (char *pwd, char *result)
{
 ...
    return result;
}

int main(void)
{
    char result[MAX] = "";
    ...
        printf ("Scrambled: %s\n", scramblePassword (test[i], result));
</code>```

Finally, your algorithm, if intended to build an array of scrambled characters from cipher will result in choosing indexes beyond the bounds of cipher resulting in undefined behavior. If the intent is to just assign a value to result[x] regardless of whether it is a valid printable ASCII value, then it may be OK. But if the first is your goal, the results of the algorithm must always result in a value that is within the bounds of cipher, e.g. something like:

```<code>         result[i] = cipher[((int)floor (cc / 16) + cc % 16) % sizeof cipher];
</code>```

Putting all those pieces together, and recalling that main is type int and therefore returns a value, you could do something like:

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

#define MAX 32

static char *scramblePassword (char *pwd, char *result)
{
    char cipher[] = "kszhxbpjvcgfqnm";
    int i;

    for (i = 0; i < (int)strlen (pwd); i++)
    {
        int cc = (int) pwd[i];
        // result[i] = cipher[(int)floor (cc / 16)] + cipher[cc % 16];
        result[i] = cipher[((int)floor (cc / 16) + cc % 16) % sizeof cipher];
    }
    result[i] = 0;  /* you MUST nul-terminate to use as a string */

    return result;
}

int main(void)
{
    char *test[] = {"test", "testtwo", "testthree"};
    char result[MAX] = "";

    for (int i = 0; i < (int)(sizeof test/sizeof *test); i++)
    {
        printf ("\nOriginal : %s\n", test[i]);
        printf ("Scrambled: %s\n", scramblePassword (test[i], result));
    }

    return 0;
}
</code>```

Example Use/Output

Which would then result in readable output of:

```<code>$ ./bin/pwscramble

Original : test
Scrambled: ffgf

Original : testtwo
Scrambled: ffgffmb

Original : testthree
Scrambled: ffgffmcff
</code>```

I'll leave it to you to research what that algorithm is actually supposed to do. Let me know if you have further questions.

Title: Creating a password scrambler

Body:
I'm trying to copy a password scrambler from Javascript to C. What it does is take the ASCII character code of the letter, floor it, divide it, and grab a random character out of a given list.

Javascript version:

function getScrambledPassword(pwd) {
    var cipher = ['k', 's', 'z', 'h', 'x', 'b', 'p', 'j', 'v', 'c', 'g', 'f', 'q', 'n', 't', 'm'];
    var result="";
    if (pwd == null)
        pwd = "";
    pwd = encodeURIComponent(pwd);
    //alert("encoded password: " + pwd);
    for(var i=0;i<pwd.length;i++) {
            var cc = pwd.charCodeAt(i);
        result += cipher[Math.floor(cc/16)] + cipher[cc%16];
    }
    //alert("scrambled password: " + result);
    return result;
}

Example of the scrambler being run: https://jsfiddle.net/w5db66va/

What I've done so far:

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

static char *scramblePassword(char *pwd)
{
    char *cipher[] = {
        "k", "s", "z", "h",
        "x", "b", "p", "j",
        "v", "c", "g", "f",
        "q", "n", "t", "m"
    };

    char *result = "";
    for(int i=0; i < strlen(pwd); i++)
    {
        int cc = (int) pwd[i];
        printf("%d", cc);
        result + cipher[floor(cc/16)] + cipher[cc%16];
    }
    return *result;
}

int main(void)
{
    char *test[] = {"test", "testtwo", "testthree"};
    for (int i=0;i < sizeof(test); i++)
    {
        printf("Original: %s", test[i]);
        printf("Scrambled: %s", scramblePassword(test[i]));
    }
}

The issue I'm experiencing is that when I run the c file (after compilation) it will not output anything at all. What am I doing wrong to the point that I cannot get this to run as I'd expect it?

Body:
Continuing from the comment, your problems run a bit deeper than you may first think. To begin, you do not want cipher to be an array of strings, you simply want it to be a character array, e.g.:

    char cipher[] = "kszhxbpjvcgfqnm";

Next, you cannot return an array that is declared within the body of a function. The memory for result is destroyed when scramblePassword returns. Your choices are (1) dynamically allocate result in scramblePassword (and free it in main), or (2) declare storage for result in main and pass it as a parameter to scramblePassword. e.g.:

#define MAX 32

static char *scramblePassword (char *pwd, char *result)
{
 ...
    return result;
}

int main(void)
{
    char result[MAX] = "";
    ...
        printf ("Scrambled: %s\n", scramblePassword (test[i], result));

Finally, your algorithm, if intended to build an array of scrambled characters from cipher will result in choosing indexes beyond the bounds of cipher resulting in undefined behavior. If the intent is to just assign a value to result[x] regardless of whether it is a valid printable ASCII value, then it may be OK. But if the first is your goal, the results of the algorithm must always result in a value that is within the bounds of cipher, e.g. something like:

         result[i] = cipher[((int)floor (cc / 16) + cc % 16) % sizeof cipher];

Putting all those pieces together, and recalling that main is type int and therefore returns a value, you could do something like:

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

#define MAX 32

static char *scramblePassword (char *pwd, char *result)
{
    char cipher[] = "kszhxbpjvcgfqnm";
    int i;

    for (i = 0; i < (int)strlen (pwd); i++)
    {
        int cc = (int) pwd[i];
        // result[i] = cipher[(int)floor (cc / 16)] + cipher[cc % 16];
        result[i] = cipher[((int)floor (cc / 16) + cc % 16) % sizeof cipher];
    }
    result[i] = 0;  /* you MUST nul-terminate to use as a string */

    return result;
}

int main(void)
{
    char *test[] = {"test", "testtwo", "testthree"};
    char result[MAX] = "";

    for (int i = 0; i < (int)(sizeof test/sizeof *test); i++)
    {
        printf ("\nOriginal : %s\n", test[i]);
        printf ("Scrambled: %s\n", scramblePassword (test[i], result));
    }

    return 0;
}

Example Use/Output

Which would then result in readable output of:

$ ./bin/pwscramble

Original : test
Scrambled: ffgf

Original : testtwo
Scrambled: ffgffmb

Original : testthree
Scrambled: ffgffmcff

I'll leave it to you to research what that algorithm is actually supposed to do. Let me know if you have further questions.


问:
Colorer Plugin in Eclipse Helios
I've been unable to get the wonderful Eclipse Colorer plugin to work with my current copy of Eclipse (Helios 64 bit).  It installs ok but whenever I attempt to open a source file I get this error:

Error in initialization of native part of the Colorer library. This can be caused by absent net_sf_colorer.dll (libnet_sf_colorer.so) library in paths of java machine. Or, colorer can't find catalog.xml file, which must be placed in '%PLUGIN_DIR%'/colorer/catalog.xml'
Could not initialize class net.sf.colorer.ParserFactory

答: It has nothing to do with the version of Eclipse. Try a 32-bit Version, AFAIK Eclipse Colorer has no support for 64-bit.</p>

ContentLicense: CC BY-SA 2.5

Title: Colorer Plugin in Eclipse Helios


问:
Android BLE Notification
I'm developing an android application using BLE. I've implemented all the basic operations like discovery, connection, and data transfer.

Now I was looking for BLE notifications, Is it possible to receive notification from BLE device when the application is not running (not even in background).

What I want to implement is the notification similar to GCM/FCM, we receive notifications in our app even though app is not running.
So want to check if similar notification mechanism is supported by BLE devices and Android framework.

I've searched for few hours now but didn't get any proper result.

If anyone can just tell me if it is supported or not?

答: If you want to receive notification event if your app is not running, you should implement Android service that continuously scan for BLE frames and ones it catch some frame that is met some parameters (for example for iBeacon it will be specific Major and Minor values; for Eddystone URL -- some specific URL etc.) -- just send intend to start your application.</p>

Title: Android BLE Notification


问:
Multi-line rounded corners with border radius
I am trying to give a span with a background a border radius. It works fine without word-wrap. But when there is word-wrap, it looks something like this:

As you can guess, I only need the edges to be rounded (except from the top left edge). I don't think I can do it with border-radius property and I have no clue how can I do this.

Any idea ?
Thanks.

edit: The Codes

```<code>.messageTextCont {
  margin-left: 5px;
  word-break: break-word;
}
.messageText {
  font-size: 17px;
  font-weight: 300;
  color: #FBFDFE;
  background-color: #402060;
  padding: 0px;
  box-shadow: 5px 0 0 #402060, -5px 0 0 #402060;
  line-height: 23px;
  -moz-border-bottom-left-radius: 5px;
  -webkit-border-bottom-left-radius: 5px;
  border-bottom-left-radius: 5px;
  -moz-border-bottom-right-radius: 5px;
  -webkit-border-bottom-right-radius: 5px;
  border-bottom-right-radius: 5px;
  -moz-border-top-right-radius: 5px;
  -webkit-border-top-right-radius: 5px;
  border-top-right-radius: 5px;
}
</code>```

edit2: I'm also OK with js solutions

edit3 : I get so close to what I want by including this :

```<code>-webkit-box-decoration-break: clone;
-o-box-decoration-break: clone;
box-decoration-break: clone;
</code>```

What this does is, it clones the styles on the first line, and applies them to the second line in case of a word-break. But the problem is as follows :

Now it exactly clones the properties of the first line and applies them to the second, making the top left and top right corner also rounded, which they should not be. To cover that up, I made the lines overlap a little bit and I got the result but now some of the letters are also overlapping. The problem is solved if I find a solution to the overlapping letters issue instead of this.

edit4 : I used box shadows :

```<code>box-shadow: 5px 0 0 #402060, -5px 0 0 #402061, -5px -3px 0 orange, 5px -3px red;
</code>```

To cover up the unwanted gaps. Now the result is like this :

The only problem I have now is that the below line overlaps the upper line. If there is some way that the upper line overlaps the bottom line, than problem solved.

答:
[SOLVED] : My solution looks like this:

```<code>.messageText {
  font-size: 17px;
  font-weight: 300;
  color: #FBFDFE;
  background-color: #402060;
  padding: 0px;
  box-shadow: 5px 0 0 #402060, -5px 0 0 #402061, 5px 5px 0 #402060, -5px 5px #402060;
  line-height: 23px;
  -moz-border-bottom-left-radius: 5px;
  -webkit-border-bottom-left-radius: 5px;
  border-bottom-left-radius: 5px;
  -moz-border-bottom-right-radius: 5px;
  -webkit-border-bottom-right-radius: 5px;
  border-bottom-right-radius: 5px;
  -moz-border-top-right-radius: 5px;
  -webkit-border-top-right-radius: 5px;
  border-top-right-radius: 5px;
  -webkit-box-decoration-break: clone;
  -o-box-decoration-break: clone;
  box-decoration-break: clone;
}
</code>```

Here is the jsFiddle:

http://jsfiddle.net/vpo2x84s/3/

Body:
I am trying to give a span with a background a border radius. It works fine without word-wrap. But when there is word-wrap, it looks something like this:

As you can guess, I only need the edges to be rounded (except from the top left edge). I don't think I can do it with border-radius property and I have no clue how can I do this.

Any idea ?
Thanks.

edit: The Codes

.messageTextCont {
  margin-left: 5px;
  word-break: break-word;
}
.messageText {
  font-size: 17px;
  font-weight: 300;
  color: #FBFDFE;
  background-color: #402060;
  padding: 0px;
  box-shadow: 5px 0 0 #402060, -5px 0 0 #402060;
  line-height: 23px;
  -moz-border-bottom-left-radius: 5px;
  -webkit-border-bottom-left-radius: 5px;
  border-bottom-left-radius: 5px;
  -moz-border-bottom-right-radius: 5px;
  -webkit-border-bottom-right-radius: 5px;
  border-bottom-right-radius: 5px;
  -moz-border-top-right-radius: 5px;
  -webkit-border-top-right-radius: 5px;
  border-top-right-radius: 5px;
}

edit2: I'm also OK with js solutions

edit3 : I get so close to what I want by including this :

-webkit-box-decoration-break: clone;
-o-box-decoration-break: clone;
box-decoration-break: clone;

What this does is, it clones the styles on the first line, and applies them to the second line in case of a word-break. But the problem is as follows :

Now it exactly clones the properties of the first line and applies them to the second, making the top left and top right corner also rounded, which they should not be. To cover that up, I made the lines overlap a little bit and I got the result but now some of the letters are also overlapping. The problem is solved if I find a solution to the overlapping letters issue instead of this.

edit4 : I used box shadows :

box-shadow: 5px 0 0 #402060, -5px 0 0 #402061, -5px -3px 0 orange, 5px -3px red;

To cover up the unwanted gaps. Now the result is like this :

The only problem I have now is that the below line overlaps the upper line. If there is some way that the upper line overlaps the bottom line, than problem solved.

Body:
[SOLVED] : My solution looks like this:

.messageText {
  font-size: 17px;
  font-weight: 300;
  color: #FBFDFE;
  background-color: #402060;
  padding: 0px;
  box-shadow: 5px 0 0 #402060, -5px 0 0 #402061, 5px 5px 0 #402060, -5px 5px #402060;
  line-height: 23px;
  -moz-border-bottom-left-radius: 5px;
  -webkit-border-bottom-left-radius: 5px;
  border-bottom-left-radius: 5px;
  -moz-border-bottom-right-radius: 5px;
  -webkit-border-bottom-right-radius: 5px;
  border-bottom-right-radius: 5px;
  -moz-border-top-right-radius: 5px;
  -webkit-border-top-right-radius: 5px;
  border-top-right-radius: 5px;
  -webkit-box-decoration-break: clone;
  -o-box-decoration-break: clone;
  box-decoration-break: clone;
}

Here is the jsFiddle:

http://jsfiddle.net/vpo2x84s/3/


问:
doesnt have any certificate/private key pair
I have been given an ad hoc distribution provisioning profile by my manager but when i am tring to select it it is saying that the profile dosent match with any certificate/private key pair in keychain.(when looked in  -> build->code signing identity -> any os</p>

答:
Ad hoc distribution provisioning profiles will not enable you to sign any code. Instead, it allows you to install and run a particular app (or a handfull of apps, depending on the settings) signed for ad hoc distribution. The profile specifies which devices the app may be run on.
You are going to import the profile and the app to iTunes and sync your iPhone to use it.

The advantage of ad hoc distribution is that you do not need to publish an app to the AppStore to distribute it, so you can quickly test minor changes on some beta tester devices. You may use this way to distribute the app to up to 100 unique devices per year.
One downside is of course that Apple cannot take care of updating and distributing your app. You have to do that manually. Furthermore, you are restricted to the 100 devices and you cannot sell your app.


问:
bazel rules for the protobuf C++ compiler
I'm using Bazel and Google's protocol buffers. I want to add a Bazel rule so I can generate the C++ API from the .proto files. In GNU make, I would do (simplified example):

```<code>%.h: %.cc
%.cc: %.proto
    protoc --cpp_out=. $<
</code>```

How can I accomplish the same (i.e. generate the API whenever mymessage.proto changes) using Bazel?

答:
Native support for cc_proto_library has recently landed in Bazel: http://bazel.build/blog/2017/02/27/protocol-buffers.html.

tl;dr, after setting your WORKSPACE file once,

```<code>cc_proto_library(
    name = "person_cc_proto",
    deps = [":person_proto"],
)

proto_library(
    name = "person_proto",
    srcs = ["person.proto"],
    deps = [":address_proto"],
)

...
</code>```

Then,

```<code>$ bazel build :person_cc_proto
</code>```

There's an example at https://github.com/cgrushko/proto_library.

The gist is that you define a proto_library to "import" you .proto file into Bazel, and cc_proto_library to compile it to C++. The protocol buffer compiler and runtimes are taken by default from @com_google_protobuf//:protoc and @com_google_protobuf_cc//:cc_toolchain, respectively.

The reason for this separation is to enable large proto graphs that need to be compiled to multiple languages.

Body:
I'm using Bazel and Google's protocol buffers. I want to add a Bazel rule so I can generate the C++ API from the .proto files. In GNU make, I would do (simplified example):

%.h: %.cc
%.cc: %.proto
    protoc --cpp_out=. $<

How can I accomplish the same (i.e. generate the API whenever mymessage.proto changes) using Bazel?

Body:
Native support for cc_proto_library has recently landed in Bazel: http://bazel.build/blog/2017/02/27/protocol-buffers.html.

tl;dr, after setting your WORKSPACE file once,

cc_proto_library(
    name = "person_cc_proto",
    deps = [":person_proto"],
)

proto_library(
    name = "person_proto",
    srcs = ["person.proto"],
    deps = [":address_proto"],
)

...

Then,

$ bazel build :person_cc_proto

There's an example at https://github.com/cgrushko/proto_library.

The gist is that you define a proto_library to "import" you .proto file into Bazel, and cc_proto_library to compile it to C++. The protocol buffer compiler and runtimes are taken by default from @com_google_protobuf//:protoc and @com_google_protobuf_cc//:cc_toolchain, respectively.

The reason for this separation is to enable large proto graphs that need to be compiled to multiple languages.


问:
how to use Scrapy to download image that needs cookie
I'm using scrapy to crawl a website
this is how I maintain the cookie jar after login

```<code>def start_requests(self):
    return [scrapy.Request("https://www.address.com", meta = {'cookiejar' : 1}, callback = self.post_login)]

def post_login(self, response):
    print('Preparing login')
    return [FormRequest.from_response(response,   #"http://www.zhihu.com/login",
                            meta = {'cookiejar' : response.meta['cookiejar']},
                            headers = self.headers,
                            formdata = {
                                'username': 'user',
                                'password': 'pass123'
                            },
                            callback = self.after_login,
                        )]
</code>```

then, each request I will need to

```<code>yield scrapy.Request(curr, meta={'cookiejar':response.meta['cookiejar']}, callback=self.parse_detail)
</code>```

Everything goes well until I need to crawl the image from the site.
I will need to use urllib.request.urlretrive(), imagePipeline of scrapy or similar tools to open the image_url.

but how can I pass my cookie jar with it? otherwise, it will be redirect to login page.

or is there a way to download the image directly with scrapy request?

Thank you, eLRuLL, for solving the problem for me
but the code need to be modified a little in python3

from io import BytesIO  instead of from StringIO import StringIO
and then use the BytesIO in the following code.

答:
the response.body has the information you need, you can later parse it to what it is.

I am not entirely sure this will work for every image file type, but you can get more information in the response.headers['content-type'] so you can know which file type it actually is and use a respective python module to handle that file type:

```<code>from PIL import Image
from StringIO import StringIO

...

    def parse_image(self, response):
        i = Image.open(StringIO(response.body))
        i.save("imagefile.png")
        ...
</code>```

with that you made a scrapy request and saved the image (this is saving in the same directory as your project).

Install PIL  with pip install Pillow

Body:
I'm using scrapy to crawl a website
this is how I maintain the cookie jar after login

def start_requests(self):
    return [scrapy.Request("https://www.address.com", meta = {'cookiejar' : 1}, callback = self.post_login)]

def post_login(self, response):
    print('Preparing login')
    return [FormRequest.from_response(response,   #"http://www.zhihu.com/login",
                            meta = {'cookiejar' : response.meta['cookiejar']},
                            headers = self.headers,
                            formdata = {
                                'username': 'user',
                                'password': 'pass123'
                            },
                            callback = self.after_login,
                        )]

then, each request I will need to

yield scrapy.Request(curr, meta={'cookiejar':response.meta['cookiejar']}, callback=self.parse_detail)

Everything goes well until I need to crawl the image from the site.
I will need to use urllib.request.urlretrive(), imagePipeline of scrapy or similar tools to open the image_url.

but how can I pass my cookie jar with it? otherwise, it will be redirect to login page.

or is there a way to download the image directly with scrapy request?

Thank you, eLRuLL, for solving the problem for me
but the code need to be modified a little in python3

from io import BytesIO  instead of from StringIO import StringIO
and then use the BytesIO in the following code.

Body:
the response.body has the information you need, you can later parse it to what it is.

I am not entirely sure this will work for every image file type, but you can get more information in the response.headers['content-type'] so you can know which file type it actually is and use a respective python module to handle that file type:

from PIL import Image
from StringIO import StringIO

...

    def parse_image(self, response):
        i = Image.open(StringIO(response.body))
        i.save("imagefile.png")
        ...

with that you made a scrapy request and saved the image (this is saving in the same directory as your project).

Install PIL  with pip install Pillow