Ne ne korsti, try catch za grananje. Koristi ascii tablicu, tryparse ili char.IsDigit(), char.IsNumber()
- +/- sve poruke
- ravni prikaz
- starije poruke gore
Svaki je jezik tražen ako si dobar u tome. I kao iskusan programer trebao bi znati da je jezik najmanje bitna stavka u životu profesionalnog programera.
Iako je tema potpuno mrtva, postavljam pitanje u nadi da možda naleti neka dobra duša s nekom pametnom dosjetkom.
Naime, pravim aplikaciju za FIFA/PES turnire u C#-u, Visual Studio, Windows Forms. Zapeo sam na liga tip turniru, odnosno round robin tournament typeu.
Dakle, korisniku je ponuđeno da izabere između 4 i 12 igrača za ligu te ih unese u bazu podataka. Nakon toga, utvara se nova forma sa tablicom i poljima za odigravanje utakmica.
Problem je sljedeći: na button click event 'izvuci protivnike' trebao bih random izbaciti dva igrača koja će međusobno igrati - svakog u jedan textbox. I nakon što oni odigraju, isto tako sljedeći par koji će igrati. Pod uvjetom da se ne ponavljaju igrači koji su već bili spojeni i da odigra svatko sa svakim. Točan broj igrača nije poznat unaprijed, odnosno može biti od 4-12 igrača. Nisam uspio osmisliti ništa što bi mi radilo.
Bilo bi zanimljivo, malo za promjenu i odmor od stackoverflowa, prodiskutirati i vidjeti ideje na domaćem forumu.
Jednostavan algoritam za round robin turnir imaš na Wikipediji.
Jednostavan algoritam za round robin turnir imaš na Wikipediji.
To je vjerojatno prva stvar koju sam otvorio kad sam se suočio s problemom.
Bilo bi jednostavno da mi je poznat broj igrača i da samo za određen broj igrača moram napraviti algoritam.
Problem je što je moguć broj igrača između 4 i 12 i korisnik bi trebao izabrati broj igrača ovisno o potrebama.
Onda bi ovisno o tome trebalo izbaciti utakmice.
Algoritam ne ovisi o broju timova. Timovi se podijele u dvije paralelne liste ("gornja" i "donja"). Prvi element gornje liste je fiksiran, a ostali se rotiraju nakon svakog kola dok se ne izradaju sve kombinacije.
Evo ti implementacija s komentarima u Pythonu 3 pa se pokušaj snaći:
# Broj timova mora biti paran pa je lakše unijeti broj parova
n = int(input('Unesi broj parova:'))
# Broj parova = n, broj timova je 2n, lista timova je [0, 1, 2, ... , 2n-1]
# Podijeli timove u 2 liste ("gornji" i "donji") s jednakim brojem timova:
gornji = list(range(n)) # timovi [0, 1, 2, ... n-1]
donji = list(range(n, n * 2)) # timovi [n, n+1, n+2, ... 2n-1]
for kolo in range(n * 2 - 1):
# Ispiši parove kola
print('Kolo', kolo)
for prvi, drugi in zip(gornji, donji):
print('{} - {}'.format(prvi, drugi))
# Rotiraj timove
# Premjesti zadnjeg iz gornje liste na kraj donje liste
zadnji_gornji = gornji.pop()
donji.append(zadnji_gornji)
# Premjesti prvog iz donje liste iza prvog iz gornje liste
prvi_donji = donji.pop(0)
gornji.insert(1, prvi_donji)
Možemo i sa jednom listom, kod svakog pomicanja elemenata na listi vršimo insert zadnjeg na index 1 a zatim zadnjeg mičemo sa liste.
class Program
{
static void Main(string[] args)
{
List<string> liga = new List<string>();
liga.Add("Hajduk");
liga.Add("Dinamo");
liga.Add("Rijeka");
liga.Add("Osijek");
liga.Add("Slaven");
liga.Add("Istra");
for(int i = 0; i < liga.Count-1; i++)
{
for (int j = 0; j < liga.Count / 2; j++)
Console.WriteLine("{0} vs {1}", liga[j], liga[liga.Count - j - 1]);
liga.Insert(1, liga[liga.Count - 1]);
liga.RemoveAt(liga.Count - 1);
Console.WriteLine();
}
}
}
Možemo i sa jednom listom, kod svakog pomicanja elemenata na listi vršimo insert zadnjeg na index 1 a zatim zadnjeg mičemo sa liste.
class Program
{
static void Main(string[] args)
{
List<string> liga = new List<string>();
liga.Add("Hajduk");
liga.Add("Dinamo");
liga.Add("Rijeka");
liga.Add("Osijek");
liga.Add("Slaven");
liga.Add("Istra");
for(int i = 0; i < liga.Count-1; i++)
{
for (int j = 0; j < liga.Count / 2; j++)
Console.WriteLine("{0} vs {1}", liga[j], liga[liga.Count - j - 1]);
liga.Insert(1, liga[liga.Count - 1]);
liga.RemoveAt(liga.Count - 1);
Console.WriteLine();
}
}
}
Samo da se osvrnem na ovo. Imaš (slučajnu?) grešku na označenoj liniji koda. Vjerujem da je na liga.Insert kao indeks trebalo ići 0, a ne 1, kako bi prebacio zadnjeg na prvo mjesto.
Inače, ako nekom bude trebalo, za neparan broj ekipa vrijedi sve isto, samo se odigrava jedna runda više (dakle i<liga.count, ne i < liga.count-1) te je drugi broj utakmica po rundi (liga.count / (n-1/2) ).
EDIT: zapravo, moja greška. Ovo kako si napravio je ispravno. Jedino u slučaju neparnog broja ekipa ide zadnji na prvo mjesto (indeks 0), u slučaju parnih ovako kako si ti napisao.
Da bi dobio ispravnu rotaciju timova jedno mjesto uvijek moraš fiksirati, nebitno da li se radi o parnom ili neparnom broju timova a nebitno i koje mjesto fiksiraš.
U biti ti kažeš da si kod neparnog broja timova fiksirao prvo mjesto drugog dijela niza a da to fiksiranje postižeš ispisom a ne insertom.
Da bi dobio ispravnu rotaciju timova jedno mjesto uvijek moraš fiksirati, nebitno da li se radi o parnom ili neparnom broju timova a nebitno i koje mjesto fiksiraš.
U biti ti kažeš da si kod neparnog broja timova fiksirao prvo mjesto drugog dijela niza a da to fiksiranje postižeš ispisom a ne insertom.
Nismo se sporazumili baš najbolje.
Fiksiranje prvog postižem insertom, ne ispisom. Samo sam htio dodati da mi ne funkcionira kada fiksiram prvo mjesto liste. Recimo paran broj igrača, 4 kluba - u trećoj rundi se ponovi jedan par iz prve runde. Što nije slučaj ako fiksiram drugo mjesto liste.
Kod neparnog broja je sve isto, samo jedna runda više se mora odigrati iz razloga jer je svako kolo jedan igrač slobodan. Dakle, samo u prvoj for petlji ide i < liga.count, ne i<liga.count-1 kao u slučaju parnog broja ekipa.
Možda sam malo spetljao s odgovorom u prošloj poruci jer sam se i sam malo spetljao, ali sve odlično radi, hvala puno na pomoći.
Pozdrav, trebam savjet oko rješavanja jednog problema. Imam datoteku iz koje trebam pročitati podatke i spremiti u objekte određene klase nakon što validiram podatke potrebno je iste spremiti u bazu.
Datoteka sadrži podatke, unutar datoteke znam poziciju na kojoj mi se nalazi svaki podatak početak i kraj podatka kojeg izvučem i spremim u objekt klase Data. Unutar datoteke nemam delimiter jer moguće je da neke vrijednosti budu odmah jedna iza druge.
Redni broj Autor Knjiga Cijena ŠifraKnjige DatumIzdavanja
Napravio sam sebi klasu Data, te svaki podatak iz linije koji čitam spremim u objekt klase Data, nakon što učitam jednu liniju iz datoteke potrebno je skupiti sve greške koje su pronađene za određeni podatak i pohraniti ih u listu lineError. Nisam htio ovdje dodavati implentaciju svih metoda jer mislim da je nepotrebno zanima me samo je li ovo dobar pristup ili postoji bolji?
Problem je kod ovoga što nakon što učitam jednu liniju potrebno je dohvatiti sve greške koje se nalaze u polju error klase Data, jer naknadno opet moram provjeriti da li se šifra knjige pronalazi u mojoj bazi. Tako da nakon što obradim sve podatke iz datoteke moram prikazati na kojoj liniji mi se nalazi greška i kojeg je tipa greška (da li je ispravna duljina podatka, da li je podatak prazan string, ...)
public class FileData
{
string fileName = "";
List<Line> lines = new List<Line>();
}
public class Line
{
List<Data> lineData = new List<Data>();
List<Error> lineError = new List<Error>();
}
public class Data
{
string fieldName = "";
int start = 0;
int end = 0;
object value = null;
Error error = null;
}
Pozdrav,
Koja je razlika između deklaracije eventa korištenjem ugrađenog delegata EventHandler<T> i pisanja svog delegata?
Primjer:
public delegate void NewClientDelegate(object sender, NewClientEventArgs e);
public event NewClientDelegate NewClientEvent;
ili
public event EventHandler<NewClientEventArgs> NewClientEvent;
U osnovi nema razlike, EventHandler<Args> je samo interni delegat od frameworka koji je isto deklariran putem delegate keyworda. Možeš njega u osnovi uzeti da nemoras deklarirati svoj delegat.
EventHandler<Args> ti je ovako napravljen:
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
Dakle jedan (vjerojatno) jednostavan problem gdje ne kužim zašto ne radi kako želim.
public class AddressEntity : IAddressEntity
{
public Guid? Id { get; set; }
public String AddressLine1 { get; set; }
public String AddressLine2 { get; set; }
public String City { get; set; }
public String State { get; set; }
public Int32 Zip { get; set; }
public string AddressDisplay {
get
{
if(!String.IsNullOrEmpty(AddressLine2)
return $"{this.AddressLine1}, {this.AddressLine2}, {this.City} {this.Zip}, {this.State}";
else
return $"{this.AddressLine1}, {this.City} {this.Zip}, {this.State}";
}
}
}
public interface IAddressEntity
{
Guid? Id { get; set; }
String AddressLine1 { get; set; }
String AddressLine2 { get; set; }
String City { get; set; }
String State { get; set; }
Int32 Zip { get; set; }
String AddressDisplay { get; }
}
Property-ije popunim mapiranjem (Automapper) iz baze.
Dakle svi property-iji budu popunjeni ali AddressDisplay bude null. Jel netko zna zašto?
Našao sam.
Problem je bio u Automapperu i mapiranju sa interface-a.
Treba naglasiti mapiranje na concrete type u ovom slučaju AddressEntity.
CreateMap<IAddressEntity, Address>().ReverseMap().As<AddressEntity>();
Pozdrav,
Trebao bih pomoć oko (pretpostavljam) jednostavnog problema vezanog uz prikaz datuma iz RSS feeda.
Datum je u klasičnom PubDate obliku za RSS feed, a ja bih trebao dd/MM/yyyy oblik (slika dolje).
Pokušao sam par rješenja što sam pronašao na stackoverflowu, ali bez uspjeha.
Model:
namespace ReadRSSFeed.Models
{
public class RSSFeed
{
public string Title { get; set; }
public string Link { get; set; }
public string Description { get; set; }
public string PubDate { get; set; }
}
}
View:
@{
ViewBag.Title = "Index";
}
<br />
<h2>RSS Feed Bug.hr</h2>
<hr />
<br />
<table class="table table-hover">
<thead>
<tr>
<th>Naslov</th>
<th>Opis</th>
<th>Datum</th>
</tr>
</thead>
<tbody>
@if (ViewBag.RSSFeed != null)
{
foreach (var item in ViewBag.RSSFeed)
{
<tr>
<td><a href="@item.Link">@item.Title</a></td>
<td>@item.Description</td>
<td>@item.PubDate</td>
</tr>
}
}
</tbody>
</table>
Controller:
namespace ReadRSSFeed.Controllers
{
public class RSSFeedController : Controller
{
public IActionResult Index()
{
WebClient wclient = new WebClient();
string RSSURL = "https://www.bug.hr/rss";
string RSSData = wclient.DownloadString(RSSURL);
XDocument xml = XDocument.Parse(RSSData);
var RSSFeedData = (from x in xml.Descendants("item")
select new RSSFeed
{
Title = ((string)x.Element("title")),
Link = ((string)x.Element("link")),
Description = ((string)x.Element("description")),
PubDate = ((string)x.Element("pubDate"))
});
ViewBag.RSSFeed = RSSFeedData;
ViewBag.URL = RSSURL;
return View();
}
}
}
Probaj u view-u nakon @item.PubDate staviti .ToString("dd/MM/yyyy")
@item.PubDate.ToString("dd/MM/yyyy")
PubDate je string pa ga zato ne možeš formatirati kao datum.
RSS koristi RFC 822 format datuma. String primljen u pubDate treba prvo pretvoriti u datum, a onda taj datum ispisati u željenom formatu.
Probaj onda ovako možda
DateTime noviDatum = DateTime.ParseExact(@item.PubDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
ili
DateTime noviDatum = DateTime.ParseExact(@item.PubDate, "d", null);
"d" je short date pattern, a "null" uzima trenutne postavke CultureInfo-a s kompa pa nakon toga formatiraj kako trebaš.
Pokušao sam već nešto slično:
string parseFormat = "dd/MM/yyyy";
DateTime date = DateTime.TryParseExact(PubDate, parseFormat, CultureInfo.InvariantCulture);
Ali dobivao sam error da PubDate ne postoji u trenutnom kontekstu.
Probat ću opet kasnije kad uhvatim vremena.
Nažalost, RSS format datuma ne odgovara točno "r" formatu datuma za ParseExact (problem je u vremenskoj zoni) pa treba ovako:
using System;
using System.Globalization;
public class Program
{
public static void Main()
{
string rawstr_pubDate = "Tue, 06 Feb 2018 15:10:00 Z";
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime pubDate = DateTime.ParseExact(rawstr_pubDate, "ddd, dd MMM yyyy HH:mm:ss K", provider);
string str_pubDate = pubDate.ToString("dd/MM/yyyy");
Console.WriteLine(str_pubDate);
}
}
Pozdrav.
Vježbam za ispit i naišao sam na jedan problem kojeg ne znam riješiti.
Imam listu objekata:
public List<Kontakti> podaci = new List<Kontakti>();
unutra imam posloženo da se spremaju podaci ovako:
private string Ime;
....
public Kontakti(string ime, string prezime, string email, string broj, string grupa)
{
this.Ime = ime;
this.Prezime = prezime;
...
}
i složio sam da mi se kako unesem podatke u listu, ispišu i listBox-u. Sada bih trebao napraviti obrnuto, kada izaberem red u listBox-u, u textboxevima mi se ispišu pojedini podaci tog objekta kojeg sam označio, probao sam razne načine, al nazalost ne znam.
Radiš u WPF-u? ako radis na MVVM način dovoljno je u XAML-u bindati textboxove na te property-e
EDIT:
Ako bas hoces kroz evente, onda bi stavio na neki selection changed na tom listbox-u, di bi onda unutar njega popunio texboxove sa izabranim objektom
EDIT2:
Ako koristiš iste textboxove za unos i pregled, onda je to loš dizajn
Lijep pozdrav!
Radim jednostavan program u c# i naletio sam na problem koji ne mogu nikako riješiti.
Napominjem da sam apsolutni početnik u programiranju s c#.
Program je namijenjen kopiranju 2 file-a u određene foldere. I radi savršeno ukoliko folder postoji.
Međutim, ono što bi ja sad želio omogućiti programu, da ukoliko foldera nema, da program ga sam napravi te onda kopira ta 2 file-a.
Znam da se koristi naredba Directory.CreateDirectory (Path) ali nikako ne uspjevam dobiti navedeno.
Čak sam pokušao da mi naredbu izvršava Background Worker, ali opet bezuspješno. Mislim, imao sam svakakvih ideja, kako to već i biva u programiranju, ali ništa mi nije uspjelo do sada, pa bi molio pomoć ako itko zna kako to omogućiti...
Moj dio koda te program izgleda ovako:
addScoreboard = subfolder.Substring(19, subfolder.Length - 19);
listBox1.Items.Add(addScoreboard); }}
private void button3_Click(object sender, EventArgs e)
{
folderBrowserDialog1.Description = "Pronađi PES6 kitserver folder";
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
textBox1.Text = folderBrowserDialog1.SelectedPath;
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string path1 = @".\KONAMI\Pro Evolution Soccer\kitserver\dat\e_text.afs\";
if (!Directory.Exists(path1))
{
DirectoryInfo di = Directory.CreateDirectory(path1);
}
}
Directory.CreateDirectory bi ti trebalo raditi,
Ako ne, što mi pada na pamet je sljedeće:
1. Vidim da ti je path1 relativan, poprilično sam siguran da ti ne treba ".\" dio na početku
2. Jesi siguran da je to točan path? Drži na umu da je relativan u odnosu na executable, koji je većinom unutar bin/ direktorija tog VS projekta
2. Provjeri permissione
Pitanjce. Nemam pojma o C#-u i pokušavam build-at projekt u sharpdevelop-u ali baci mi 10 errora.
Prvi na koji se buni:
publicstaticTimeSpan ReadWriteTimeout => CallContextSettings<HttpSettings>.Settings.ReadWriteTimeout;
Smeta mu "=>" , a error je CS1002
I onda se na kraju te linije buni na ";" - CS 1519
Svaka pomoć dobrodošla.
Hvala!
Pitanjce. Nemam pojma o C#-u i pokušavam build-at projekt u sharpdevelop-u ali baci mi 10 errora.
Prvi na koji se buni:
publicstaticTimeSpan ReadWriteTimeout => CallContextSettings<HttpSettings>.Settings.ReadWriteTimeout;
Smeta mu "=>" , a error je CS1002
I onda se na kraju te linije buni na ";" - CS 1519
Svaka pomoć dobrodošla.
Hvala!
Novija sintaksa koju compiler očito ne podržava. Ne znam ništa o SharpDevelop-u no pretpostavljam da se nekako može promijeniti putanja do compiler-a (csc.exe za C#).
Umjesto toga, preporučio bih ti da se poštediš muke i instaliraš VS 2017 Community koji je posve besplatan.

