diff --git a/20240919/ConsoleApp1/.vs/ConsoleApp1/FileContentIndex/72ab0ad0-d936-423c-8f34-b3444a674a60.vsidx b/20240919/ConsoleApp1/.vs/ConsoleApp1/FileContentIndex/72ab0ad0-d936-423c-8f34-b3444a674a60.vsidx new file mode 100644 index 0000000..bd71998 Binary files /dev/null and b/20240919/ConsoleApp1/.vs/ConsoleApp1/FileContentIndex/72ab0ad0-d936-423c-8f34-b3444a674a60.vsidx differ diff --git a/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/.suo b/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/.suo new file mode 100644 index 0000000..64b79ed Binary files /dev/null and b/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/.suo differ diff --git a/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/DocumentLayout.backup.json b/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/DocumentLayout.backup.json new file mode 100644 index 0000000..58595c9 --- /dev/null +++ b/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/DocumentLayout.backup.json @@ -0,0 +1,37 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\szabomarton\\Desktop\\C#\\ProgaOra\\20240919\\ConsoleApp1\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{36A44E1B-CB62-446B-86E4-AA211A1C4DFD}|ConsoleApp1\\ConsoleApp1.csproj|c:\\users\\szabomarton\\desktop\\c#\\progaora\\20240919\\consoleapp1\\consoleapp1\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{36A44E1B-CB62-446B-86E4-AA211A1C4DFD}|ConsoleApp1\\ConsoleApp1.csproj|solutionrelative:consoleapp1\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Program.cs", + "DocumentMoniker": "C:\\Users\\szabomarton\\Desktop\\C#\\ProgaOra\\20240919\\ConsoleApp1\\ConsoleApp1\\Program.cs", + "RelativeDocumentMoniker": "ConsoleApp1\\Program.cs", + "ToolTip": "C:\\Users\\szabomarton\\Desktop\\C#\\ProgaOra\\20240919\\ConsoleApp1\\ConsoleApp1\\Program.cs", + "RelativeToolTip": "ConsoleApp1\\Program.cs", + "ViewState": "AgIAADEAAAAAAAAAAAAcwEEAAAAoAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-09-19T06:52:49.159Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/DocumentLayout.json b/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/DocumentLayout.json new file mode 100644 index 0000000..ad977d0 --- /dev/null +++ b/20240919/ConsoleApp1/.vs/ConsoleApp1/v17/DocumentLayout.json @@ -0,0 +1,37 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\szabomarton\\Desktop\\C#\\ProgaOra\\20240919\\ConsoleApp1\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{36A44E1B-CB62-446B-86E4-AA211A1C4DFD}|ConsoleApp1\\ConsoleApp1.csproj|c:\\users\\szabomarton\\desktop\\c#\\progaora\\20240919\\consoleapp1\\consoleapp1\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{36A44E1B-CB62-446B-86E4-AA211A1C4DFD}|ConsoleApp1\\ConsoleApp1.csproj|solutionrelative:consoleapp1\\program.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "Program.cs", + "DocumentMoniker": "C:\\Users\\szabomarton\\Desktop\\C#\\ProgaOra\\20240919\\ConsoleApp1\\ConsoleApp1\\Program.cs", + "RelativeDocumentMoniker": "ConsoleApp1\\Program.cs", + "ToolTip": "C:\\Users\\szabomarton\\Desktop\\C#\\ProgaOra\\20240919\\ConsoleApp1\\ConsoleApp1\\Program.cs", + "RelativeToolTip": "ConsoleApp1\\Program.cs", + "ViewState": "AgIAADEAAAAAAAAAAAAcwEMAAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2024-09-19T06:52:49.159Z", + "EditorCaption": "" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/20240919/ConsoleApp1/ConsoleApp1.sln b/20240919/ConsoleApp1/ConsoleApp1.sln new file mode 100644 index 0000000..30b248b --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35222.181 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{36A44E1B-CB62-446B-86E4-AA211A1C4DFD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {36A44E1B-CB62-446B-86E4-AA211A1C4DFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36A44E1B-CB62-446B-86E4-AA211A1C4DFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36A44E1B-CB62-446B-86E4-AA211A1C4DFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36A44E1B-CB62-446B-86E4-AA211A1C4DFD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AEBD4DC6-C386-4383-A868-204B9E548812} + EndGlobalSection +EndGlobal diff --git a/20240919/ConsoleApp1/ConsoleApp1/App.config b/20240919/ConsoleApp1/ConsoleApp1/App.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/20240919/ConsoleApp1/ConsoleApp1/ConsoleApp1.csproj b/20240919/ConsoleApp1/ConsoleApp1/ConsoleApp1.csproj new file mode 100644 index 0000000..57bf964 --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/ConsoleApp1.csproj @@ -0,0 +1,53 @@ + + + + + Debug + AnyCPU + {36A44E1B-CB62-446B-86E4-AA211A1C4DFD} + Exe + ConsoleApp1 + ConsoleApp1 + v4.7.2 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/20240919/ConsoleApp1/ConsoleApp1/Program.cs b/20240919/ConsoleApp1/ConsoleApp1/Program.cs new file mode 100644 index 0000000..fe55c9c --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/Program.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Diagnostics.Tracing; +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; + +namespace ConsoleApp1 +{ + internal class Program + { + static void Main(string[] args) + { + DataRead("C:\\Users\\szabomarton\\Desktop\\C#\\ProgaOra\\20240919\\termekek.csv", ';'); + //Feladat1(); + Feladat2(); + Feladat3(); + Feladat4(); + + Console.ReadLine(); + } + + static void Feladat1() + { + int fizetes_sum = Fizetes_SUM(Data.alkalmazottak); + double fizetes_avg = Fizetes_AVG(Data.alkalmazottak); + Console.WriteLine($"A fizetések összege: {fizetes_sum}"); + Console.WriteLine($"A fizetések Átlaga: {fizetes_avg:F2}"); + } + + static int Fizetes_SUM(List T) { + var result = T.Select(x => x.fizetes); + return result.Sum(); + } + + static double Fizetes_AVG(List T) + { + IEnumerable asd = T.Select(x => x.fizetes); + return asd.Average(); + } + + static void Feladat2() + { + foreach (var item in Data.raktar) + { + Console.WriteLine($"{item.nev}"); + } + } + + static void Feladat3() + { + var result = Data.raktar.GroupBy(y => y.kategoria).Select(x => new {x.Key, darab = x.Count()}); + foreach (var item in result) + { + Console.WriteLine($"{item.Key} {item.darab}"); + } + + } + + static void Feladat4() + { + var legolcsobb = Data.raktar.OrderBy(x => x.ar).Select(y => new {y.nev, y.ar}); + Console.WriteLine(legolcsobb); + } + + + static void DataRead(string path, char splitchar) + { + using (StreamReader streamReader = new StreamReader(path)) + { + string line = streamReader.ReadLine(); + line = streamReader.ReadLine(); + while (line != null) + { + string[] datas = line.Split(splitchar); + + TermekAdd(datas); + + line = streamReader.ReadLine(); + } + } + } + + static void TermekAdd(string[] datas) + { + Termek termek = new Termek(datas[0], datas[1], Int32.Parse(datas[2])); + Data.raktar.Add(termek); + } + + static void AlkalmazottAdd(string[] datas) + { + Alkalmazott alkalmazott = new Alkalmazott(datas[0], Int32.Parse(datas[1])); + Data.alkalmazottak.Add(alkalmazott); + } + } + + public class Alkalmazott + { + public string nev; + public int fizetes; + + public Alkalmazott(string Nev, int Fizetes) + { + nev = Nev; + fizetes = Fizetes; + } + } + + public class Termek + { + public string nev; + public string kategoria; + public int ar; + + public Termek(string Nev, string Kategoria, int Ar) + { + nev = Nev; + kategoria = Kategoria; + ar = Ar; + } + } + + public static class Data + { + public static List alkalmazottak = new List (); + public static List raktar = new List (); + } +} diff --git a/20240919/ConsoleApp1/ConsoleApp1/Properties/AssemblyInfo.cs b/20240919/ConsoleApp1/ConsoleApp1/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a699f02 --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ConsoleApp1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConsoleApp1")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("36a44e1b-cb62-446b-86e4-aa211a1c4dfd")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.exe b/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.exe new file mode 100644 index 0000000..35bb8ba Binary files /dev/null and b/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.exe differ diff --git a/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.exe.config b/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.exe.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.exe.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.pdb b/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.pdb new file mode 100644 index 0000000..874dca3 Binary files /dev/null and b/20240919/ConsoleApp1/ConsoleApp1/bin/Debug/ConsoleApp1.pdb differ diff --git a/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs new file mode 100644 index 0000000..3871b18 --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/.NETFramework,Version=v4.7.2.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] diff --git a/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.AssemblyReference.cache b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.AssemblyReference.cache new file mode 100644 index 0000000..126ed02 Binary files /dev/null and b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.AssemblyReference.cache differ diff --git a/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.CoreCompileInputs.cache b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..0be8d26 --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +137ddb1975586287657f37337b64d051167bb6a147915d9fb5b8eb94b1093509 diff --git a/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.FileListAbsolute.txt b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..aabaa8f --- /dev/null +++ b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.csproj.FileListAbsolute.txt @@ -0,0 +1,7 @@ +C:\Users\szabomarton\Desktop\C#\ProgaOra\20240919\ConsoleApp1\ConsoleApp1\bin\Debug\ConsoleApp1.exe.config +C:\Users\szabomarton\Desktop\C#\ProgaOra\20240919\ConsoleApp1\ConsoleApp1\bin\Debug\ConsoleApp1.exe +C:\Users\szabomarton\Desktop\C#\ProgaOra\20240919\ConsoleApp1\ConsoleApp1\bin\Debug\ConsoleApp1.pdb +C:\Users\szabomarton\Desktop\C#\ProgaOra\20240919\ConsoleApp1\ConsoleApp1\obj\Debug\ConsoleApp1.csproj.AssemblyReference.cache +C:\Users\szabomarton\Desktop\C#\ProgaOra\20240919\ConsoleApp1\ConsoleApp1\obj\Debug\ConsoleApp1.csproj.CoreCompileInputs.cache +C:\Users\szabomarton\Desktop\C#\ProgaOra\20240919\ConsoleApp1\ConsoleApp1\obj\Debug\ConsoleApp1.exe +C:\Users\szabomarton\Desktop\C#\ProgaOra\20240919\ConsoleApp1\ConsoleApp1\obj\Debug\ConsoleApp1.pdb diff --git a/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.exe b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.exe new file mode 100644 index 0000000..35bb8ba Binary files /dev/null and b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.exe differ diff --git a/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.pdb b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.pdb new file mode 100644 index 0000000..874dca3 Binary files /dev/null and b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/ConsoleApp1.pdb differ diff --git a/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache new file mode 100644 index 0000000..04064f3 Binary files /dev/null and b/20240919/ConsoleApp1/ConsoleApp1/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache differ diff --git a/20240919/alkalmazottak.txt b/20240919/alkalmazottak.txt new file mode 100644 index 0000000..a0a77dd --- /dev/null +++ b/20240919/alkalmazottak.txt @@ -0,0 +1,18 @@ +Név,Fizetés +Kiss Péter,300000 +Nagy László,400000 +Szabó Erika,350000 +Tóth Gábor,500000 +Molnár András,280000 +Varga Judit,450000 +Farkas Béla,370000 +Balogh Ágnes,330000 +Kovács Dóra,380000 +Boros Anikó,410000 +Lukács Gábor,430000 +Horváth István,295000 +Vörös Anna,310000 +Veres Katalin,470000 +Fekete Csaba,440000 +Fehér Levente,360000 +Simon László,300000 diff --git a/20240919/termekek.csv b/20240919/termekek.csv new file mode 100644 index 0000000..403cd2d --- /dev/null +++ b/20240919/termekek.csv @@ -0,0 +1,18 @@ +Név;Kategória;Ár +Laptop;Elektronikai eszközök;900000 +Egér;Elektronikai eszközök;2000 +Szék;Bútorok;50000 +Asztal;Bútorok;150000 +Ceruza;Irodai eszközök;200 +Nyomtató;Elektronikai eszközök;30000 +Toll;Irodai eszközök;300 +Polc;Bútorok;10000 +Lámpa;Bútorok;7000 +Hűtőszekrény;Elektronikai eszközök;120000 +Tűzőgép;Irodai eszközök;800 +Számítógép;Elektronikai eszközök;150000 +Fotel;Bútorok;20000 +Papír;Irodai eszközök;100 +Tányér;Konyhai eszközök;5000 +Bögre;Konyhai eszközök;600 +Serpenyő;Konyhai eszközök;4000 diff --git a/linq_anyag b/linq_anyag index aabb913..fcef298 100644 --- a/linq_anyag +++ b/linq_anyag @@ -50,4 +50,58 @@ Elemek kiválasztása: ElementAt(index) ElementAtOrDefault(index) - \ No newline at end of file + +Ismétlődések kiszűrése + Ismétlődés kiszűrésére a Distinct metódus alkalmazható. + Alkalmazásának feltétele, hogy ha a típusunk egy összetett típus, ami több elemet tartalmaz, akkor rendelkezzen egy megfelelően felülírt Equals metódussal. + Alternatívként adhatunk meg egy IEqualityComparer interface metódus-t megvalósító típus példányt. + + var egyedix = elemek.DistinctBy(i => i.x); + +Aggregáló műveletek + Ha kollekció eredményének számosságára vagyunk kíváncsiak, akkor a Count() metódus alkalmazhatjuk. + var parosx = elemek.Count(i => i.X%2 ==0); + +Feltételek esetén, ha azt szeretnénk kiértékelni, hogy egyáltalán van e eredménye a keresésnek, akkor a Cpunt() > 0 kifejezés erősen kerülendő, mert ez végig megy a kollekción és végigszámolja az elemeket. +Helyette az Any() metódust használjuk, ami eleve erre lett kitalálva. +Az Any() igaz értéket ad vissza, ha az IEnumerable típisusnk tartalmaz elemeket. +Paraméterrel is kiegészíthetjük. +Ebben az esetben azt mondja meg, hogy a kollekció tartalmaz-e a feltételnek megfelelő elemet. + +Ha egy kollekció esetén minimum vagy maximum értékre vagyunk kíváncsiak, akkor a Min() és Max() metódusokat alkalmazhatjuk. +Ha a kollekció szám típusokból áll, akkor paraméter nem kell adnunk. +Ellenkező esetben kell egy kifejezés, ami megmondja, hogy mi alapján számolódjon meg a min és max érték. +Átlagosra hasonló működéssel az Avg() metódus alkalmazható. + +var MaxX = elemek.Max( i => i.X); + +var MinY = elemek.Min( i => i.Y); + +vor avg = elemek.Avg( i => i.Y * i.X); + +int[] ints1 = {5,56,535434,435473854,45}; +int[] ints2 = {58,56448,38647,4,45,5,6,56}; + +//unió +IEnumerable union = ints1.Union(ints2); + +//metszet +IEnumerable intersect = ints1.Intersect(ints2); + +// különbség +IEnumerable except = ints1.Except(ints2); + +//Concat +var concatenated = ints1.Concat(ints2); + +Ha olyan módon szeretnénk összefűzni elemeket, hogy 1 elemet szeretnénk venni az első kollekcióóból, majd egy elemet szeretnénk a második kollekcióból. +Erre a zip művelet képes +ami a ValueTuple formában adja vissza az elemeket. + +var result = a.zip(b); + +szeletelés +Chunk műveletet, amivel egy IEnumerable típust fel tudunk szeletelni több, megadott maximum elemszámú T típusú tömbre. +int[] a = {1,2,3,4}; +IEnumerable result = a.chunk(2); +//[1,2] és [3,4] tömböket produkál