|
|
You are bound to get a DivideByZeroInExceptionException
|
|
|
|
|
Luc?! 'Zat really you? 
|
|
|
|
|
Yep. Sprinkling Seasons Exceptions.
|
|
|
|
|
Hey Luc, whaddup?
|
|
|
|
|
Hi Nish,
I'm just checking both sides of the moon. It seems rather dark either way...
|
|
|
|
|
Heheh
|
|
|
|
|
 As others have said, this is the sort of thing that's better served using a procedural iterator method than trying to fudge it with LINQ.
Something like this would work, and would only require one pass through the source list:
public static IEnumerable<KeyValuePair<T1, List<T1>>> ToChunkedKvPList<T1>(this IEnumerable<T1> source, int chunksz)
{
if (source == null) throw new ArgumentNullException("source");
if (chunksz <= 0) throw new ArgumentOutOfRangeException("chunksz", "The chunk size must be greater than 0.");
return ToChunkedKvPListIterator(source, chunksz);
}
private static IEnumerable<KeyValuePair<T1, List<T1>>> ToChunkedKvPListIterator<T1>(IEnumerable<T1> source, int chunksz)
{
int currentChunkSize = 0;
T1 currentHeader = default(T1);
var currentChunk = new List<T1>(chunksz);
foreach (T1 item in source)
{
if (currentChunkSize == 0)
{
currentHeader = item;
}
else
{
currentChunk.Add(item);
}
currentChunkSize++;
if (currentChunkSize == chunksz)
{
yield return new KeyValuePair<T1, List<T1>>(currentHeader, currentChunk);
currentChunkSize = 0;
currentHeader = default(T1);
currentChunk = new List<T1>(chunksz);
}
}
if (currentChunkSize != 0)
{
yield return new KeyValuePair<T1, List<T1>>(currentHeader, currentChunk);
}
}
The only thing you lose is the exception if the source list count isn't a precise multiple of the chunk size, which would require multiple passes.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Very interesting, Richard, thanks ! I do not see using Linq as shown here as "fudging" in any sense of that word, but perhaps that word connotes something for you I am unaware of. As I said to Piebald, the example here was not meant to show all the fire-proofing/validation I would expect to see in "production code," but, of course, I am happy to see you included what you felt was needed.
My hypothetical take-away from your, and others', responses here is:
1. using the 'Count() method on an IEnumerable is either, or both:
a. expensive in terms of memory or time of computation
b. may "break" re-using that IEnumerable depending on what the IEnumerable base-Type is.
As time, and pending eye-surgery, permits, I'll look into those.
cheers, Bill
«Tell me and I forget. Teach me and I remember. Involve me and I learn.» Benjamin Franklin
|
|
|
|
|
LINQ is very good at doing specific things, but when you need to introduce modified closures to make it do what you need, I consider that a "fudge".
The basic Count() method[^] has special cases for ICollection and ICollection<T> ; for everything else, it has to iterate the entire list. As you say, depending on the source sequence, this could be expensive in terms of memory and/or time. It could even break if the source sequence is not deterministic.
The version that uses Count() would also fail to work with infinite sequences, whereas the version that doesn't would just produce an infinite sequence of transformed values:
IEnumerable<int> AskDeepThought()
{
while (true)
{
yield return 42;
}
}
var answers = AskDeepThought().ToChunkedKvPList().Take(42);
BillWoodruff wrote: pending eye-surgery
Hope it goes well.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks, Richard,
I find myself struggling to understand what you refer to by "modified closures;" and, to imagine what an IEnumerable that was not "sequence deterministic" would be.
As you may have noticed from the edit to my original post here, I have verified that the code will work on both Stacks, and Queues, as-is.
I am aware that you have a deep understanding of Linq; have you ever thought about writing articles, or tip/tricks, for CP on Linq ? I find your Tips/Tricks are always very valuable.
cheers, Bill
«Tell me and I forget. Teach me and I remember. Involve me and I learn.» Benjamin Franklin
|
|
|
|
|
BillWoodruff wrote: modified closures
In your original method, you've captured / "closed over" the variables chunksz , listsz and ndx . In the lambda method you've passed to GroupBy , you modify the ndx variable. Hence it's a "modified closure".
It's not technically wrong, and the code will work as expected, but it "feels" icky. (Hence your post asking if there was a way to avoid it.)
BillWoodruff wrote: an IEnumerable that was not "sequence deterministic"
An example would be the value returned from the BlockingCollection(T).GetConsumingEnumerable method[^] - once it has returned a value, that value is removed from the collection. If you iterate twice, you'll get no items the second time.
using (var bc = new BlockingCollection<int>())
{
Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
bc.Add(i);
Thread.Sleep(100);
}
bc.CompleteAdding();
});
var list = bc.GetConsumingEnumerable();
Console.WriteLine("{0} items in the collection.", list.Count());
Console.WriteLine("Iterate the list:");
foreach (var item in list)
{
Console.WriteLine(item);
}
Console.WriteLine("Iterate again:");
foreach (var item in bc.GetConsumingEnumerable())
{
Console.WriteLine(item);
}
}
BillWoodruff wrote: have you ever thought about writing articles, or tip/tricks, for CP on Linq ?
Two problems with that: coming up with ideas that haven't already been done, and finding the time.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks, Richards for the substantive response.Richard Deeming wrote: It's not technically wrong, and the code will work as expected, but it "feels" icky. (Hence your post asking if there was a way to avoid it.) My thought was that there was probably a way using some Linq operator that supports indexing natively, such as Select, which could be used ... I am not educated enough to feel the "ick"
'BlockingCollection: another .NET Type I've never had looked at.
cheers, Bill
«Tell me and I forget. Teach me and I remember. Involve me and I learn.» Benjamin Franklin
|
|
|
|
|
So something like this:
return source
.Select((item, index) => new
{
item,
chunk = index / chunksz
})
.GroupBy(
x => x.chunk,
x => x.item,
(key, grp) => KeyValuePair.Create(grp.First(), grp.Skip(1).ToList())
);
(Using the KeyValuePair factory method from this post[^].)
Of course, that still wouldn't work with an infinite sequence, as GroupBy has to iterate the entire sequence before returning anything.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That code is a Zen koan !
[cue sound of one-hand clapping]
very appreciated, Bill
«Tell me and I forget. Teach me and I remember. Involve me and I learn.» Benjamin Franklin
|
|
|
|
|
I have a button in a datagrid and another in the toolstrip bar, each one invoking exactly the same function ('Gravar') whose goal is to fill or update the datagrid whose columns are composed of text and other columns with checkboxes, but the one from the datagrid updates the checkboxes while the other doesn't. Why is this happening?
|
|
|
|
|
How would we know?
We can't see your screen, access your HDD, or read your mind, so we have no idea how you coded your method!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
 In the following code, the button 'bt_gravar_click' which belongs to a toolstrip bar doesn´t fill correctly the check boxes whereas the button ' bt_preencher', which is a normal button in datagrid, does. The code is not well indented.
private void bt_gravar_Click(object sender, EventArgs e)
{
Gravar();
}
private void bt_preencher_Click(object sender, EventArgs e)
{
Gravar();
}
public void Gravar()
{
BD_Conexao();
if (grid_lic.CurrentRow.Cells[3].Value.ToString() != "" | grid_lic.CurrentRow.Cells[3].Value.ToString() == "True")
bloqueador = 1;
else
bloqueador = 0;
if (grid_lic.CurrentRow.Cells[7].Value.ToString() != "" | grid_lic.CurrentRow.Cells[7].Value.ToString() == "True")
EArtigo = 1;
else
EArtigo = 0;
string Cmd = "Select * from lojas where NIF ='" + grid_lic.CurrentRow.Cells[1].Value + "' and loja ='" + grid_lic.CurrentRow.Cells[2].Value + "'";
OdbcCommand cm2 = new OdbcCommand(Cmd, con);
OdbcDataReader dr = cm2.ExecuteReader();
string cmd = "insert into licenciamentoloja (bloqueador, EArtigo) values (?, ?)";
OdbcCommand cm = new OdbcCommand(cmd, con);
cm.Parameters.AddWithValue("@bloqueador", bloqueador);
cm.Parameters.AddWithValue("@EArtigo", EArtigo);
cm.ExecuteNonQuery();
Consulta()
}
public void Consulta()
{
con = new OdbcConnection("driver= {MySQL ODBC 5.1 Driver};server=xxx; database=licenciamento; uid=estagio; password=1234; option = 3 ");
con.Open();
OdbcCommand Command = con.CreateCommand();
Command.CommandText = "select licenciamentoloja.bloqueador, licenciamentoloja.Artigo from licenciamentoloja;"
Command.CommandType = CommandType.Text;
Command.Connection = con;
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = Command;
_ds = new DataSet();
dt = _ds.Tables["filtro"];
adapter.Fill(_ds, "filtro");
grid_lic.DataSource = _ds;
grid_lic.DataMember = _ds.Tables[0].TableName;
grid_lic.DataMember = "filtro";
}
public void BD_Conexao()
{
try
{
OdbcConnection con = new OdbcConnection("driver= {MySQL ODBC 5.1 Driver};server=xxx; database=licenciamento; uid=estagio; password=1234; option = 3 ");
con.Open();
}
catch (Exception ex)
{
Console.WriteLine("Erro na ligação à base de dados. \n{0}", ex.Message);
return;
}
}
|
|
|
|
|
Just because you are calling the same method, doesn't mean the conditions are the same.
In particular, does the grid_lic.CurrentRow reference what you think it does?
So start with the debugger. Put a breakpoint on the first line in the Gravar method, and start stepping through the code looking at exactly what happens, and comparing that with what you expected to happen. When the two differ, it should give you a little information as to what it at fault.
We can't do that for you: we don't have access to your database.
But...some of that code is rather odd. Your BD_Conexao method in particular does nothing at all that affects the outside world, as the local con variable masks the global one used by the calling routine.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
And how do you tkink am I suppose to find the cause of the problem with break points if the break point pointing to the value of checkboxes, shows me the wrong value when I use the button from the toolbar and the correct value when I use the button from the datagrid? Does this takes me to any conclusion? It just confirms that it is not filling the checkboxes correctly, not why this should be happening.
|
|
|
|
|
Member 11449447 wrote: It just confirms that it is not filling the checkboxes correctly, not why this should be happening. Actually, it confirms that there is a bug in your code, and the debugger will help you to identify where that bug is.
|
|
|
|
|
So now you know the value being returned is not correct. Now you have to use the debugger to find out why. It's a tool that allows you to inspect variable contents as the code is running, so USE IT! Does the code that populates the controls work correctly? You better go verify that.
Also, the debugger is a tool that is used to correct YOU. Your understanding of what the code is doing is usually wrong. The debugger helps you understand your code AND DATA better. In development work, chances are high that your code is written to handle perfect data but it falls on its face when it encounters something that isn't perfect. The debugger helps you find these cases and adjust your code.
|
|
|
|
|
Member 11449447 wrote: string Cmd = "Select * from lojas where NIF ='" + grid_lic.CurrentRow.Cells[1].Value + "' and loja ='" + grid_lic.CurrentRow.Cells[2].Value + "'";
OdbcCommand cm2 = new OdbcCommand(Cmd, con);
OdbcDataReader dr = cm2.ExecuteReader();
Your code is vulnerable to SQL Injection[^]. NEVER use string concatenation to build a SQL query. ALWAYS use a parameterized query.
Also, you should always wrap objects which implement IDisposable in a using block, to ensure that their resources are released properly.
using (OdbcConnection con = new OdbcConnection("driver= {MySQL ODBC 5.1 Driver};server=xxx; database=licenciamento; uid=estagio; password=1234; option = 3 "))
{
con.Open();
using (OdbcCommand cm2 = new OdbcCommand("Select * from lojas where NIF = ? and loja = ?", con))
{
cm2.Parameters.AddWithValue("NIF", grid_lic.CurrentRow.Cells[1].Value);
cm2.Parameters.AddWithValue("loja", grid_lic.CurrentRow.Cells[2].Value);
using (OdbcDataReader dr = cm2.ExecuteReader())
{
}
}
using (OdbcCommand cm = new OdbcCommand("insert into licenciamentoloja (bloqueador, EArtigo) values (?, ?)", con))
{
cm.Parameters.AddWithValue("@bloqueador", bloqueador);
cm.Parameters.AddWithValue("@EArtigo", EArtigo);
cm.ExecuteNonQuery();
}
}
Member 11449447 wrote: if (grid_lic.CurrentRow.Cells[3].Value.ToString() != "" | grid_lic.CurrentRow.Cells[3].Value.ToString() == "True")
You're using the non-short-circuiting boolean operator | . In the vast majority of cases (including this one), that's the wrong operator to use. You should use the short-circuiting operator || instead.
if (grid_lic.CurrentRow.Cells[3].Value.ToString() != "" || grid_lic.CurrentRow.Cells[3].Value.ToString() == "True")
However, that still doesn't make any sense. If the value of the cell is not an empty string, then the first condition is true. If it is an empty string, then there's no way it can be equal to "True", so the second condition is false. The whole statement is equivalent to:
if (grid_lic.CurrentRow.Cells[3].Value.ToString() != "")
Member 11449447 wrote: public void BD_Conexao()
As Griff said, this method does nothing useful. It looks like you're trying to initialize and open a connection object stored in a class-level field called con , but you've declared a local variable of the same name instead.
Storing connection objects in fields is generally a bad idea. You should created and open the connection within the method that uses it, wrapped in a using block. Have a single method to create and open a new connection object, and return that connection:
public OdbcConnection BD_Conexao()
{
var result = new OdbcConnection("driver= {MySQL ODBC 5.1 Driver};server=xxx; database=licenciamento; uid=estagio; password=1234; option = 3 ");
result.Open();
return result;
}
Then call that method from your other methods when you need to connect to the database:
using (OdbcConnection con = BD_Conexao())
{
...
}
Everything you wanted to know about SQL injection (but were afraid to ask) | Troy Hunt[^]
How can I explain SQL injection without technical jargon? | Information Security Stack Exchange[^]
Query Parameterization Cheat Sheet | OWASP[^]
SQL injection attack mechanics | Pluralsight [^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I´ve made all the changes according to your advices and it remains with the same error. But I solved this issue by using preformclick event in the button not working to triger the button click event that works, and setting this invisible in the datagrid (not by the invisible property but rather by managing the colors in the design).
Regarding your observation concerning the expression:
if (grid_lic.CurrentRow.Cells[3].Value.ToString() != "" || grid_lic.CurrentRow.Cells[3].Value.ToString() == "True")
bloqueador = 1;
else
bloqueador = 0;
it should be an '&' instead of a '||', the same is to say:
if(grid_lic.CurrentRow.Cells[3].Value.ToString() == "True")
bloqueador = 1;
else
bloqueador = 0;
which is equivalent to:
if(grid_lic.CurrentRow.Cells[3].Value.ToString() == "False" ||grid_lic.CurrentRow.Cells[3].Value.ToString() == "" )
bloqueador = 0;
else
bloqueador = 1;
since cell[3] or is empty or has the value 'true' or 'false'.
|
|
|
|
|
how to parse xml recusive based on directory and search criteria to get file name
<FileSystem>
<Drives>
<Drive name="C:">
<Folder name="data">
<Folder name="CSLogs">
<Folder name="Applications">
<Folder name="Citrix">
<Folder name="XenDesktop Installer">
<Folder name="MSI Log Files">
<File Name="BrokerAgent_x64311392187.txt" />
<File Name="CitrixCse_x641365171634.txt" />
<File Name="DirectorVDAplugin_x64276896625.txt" />
<File Name="IcaWS_x64397216209.txt" />
<File Name="MachineIdentityServiceAgent_x64492650649.txt" />
<File Name="MachineManagementProvider_x64407826716.txt" />
<File Name="personalvDisk_x64359317401.txt" />
<File Name="profilemgt_x641717284940.txt" />
<File Name="PzAppV_VDA_x641126819295.txt" />
<File Name="UpsClient_x641677360187.txt" />
<File Name="VdaMonitorPlugin_x64958367608.txt" />
<File Name="WMIProxy_x64801526517.txt" />
</Folder>
<File Name="XenDesktop Installation.log" />
</Folder>
<File Name="23157CIXXenDesktopVirtFx_Popup.log" />
<File Name="FixPolicyCorruption.ps1.log" />
</Folder>
modified 7-Jan-16 23:08pm.
|
|
|
|
|